diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e06f366 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,479 @@ +# FT546MWS 项目说明 + +## 项目概述 + +FT546MWS 是一个基于 **若依(RuoYi)** 框架定制的制造执行系统(MES)和仓库管理系统(WMS),采用前后端分离架构。项目基于若依 v3.9.0 进行二次开发,集成了工业物联网(IIoT)功能和 AI 能力。 + +### 核心技术栈 + +#### 后端技术 +- **框架**: Spring Boot 3.5.4 +- **Java 版本**: Java 17 +- **数据库**: SQL Server 2019 (主库), MariaDB (从库, 可选) +- **ORM**: MyBatis 3.0.4 + MyBatis-Plus 3.5.14 +- **连接池**: Druid 1.2.23 +- **缓存**: Redis +- **权限认证**: JWT + Spring Security +- **API 文档**: SpringDoc OpenAPI (Swagger) +- **定时任务**: Quartz +- **代码生成**: Velocity 模板引擎 +- **工业通信**: HslCommunication 3.7.0 (支持 PLC、Modbus 等工业协议) +- **AI 集成**: Spring AI 1.0.1 (OpenAI 兼容接口, 向量数据库) +- **MCP 协议**: Spring AI MCP Client +- **工具库**: Hutool 5.8.27, FastJSON2 2.0.57, POI 4.1.2 + +#### 前端技术 +- **框架**: Vue 2.6.12 +- **UI 组件库**: Element UI 2.15.14 +- **状态管理**: Vuex 3.6.0 +- **路由**: Vue Router 3.4.9 +- **图表**: ECharts 5.4.0 +- **国际化**: Vue I18n 7.3.2 +- **构建工具**: Vue CLI 4.4.6 +- **其他**: Axios, Quill (富文本编辑器), VueCropper (图片裁剪) + +### 项目架构 + +这是一个典型的前后端分离的 Maven 多模块项目,包含以下模块: + +``` +FT546MWS/ +├── ruoyi-admin/ # Web 服务入口模块(启动类、控制器) +├── ruoyi-framework/ # 框架核心模块(安全配置、拦截器、工具类) +├── ruoyi-system/ # 系统管理模块(用户、角色、菜单、部门等) +├── ruoyi-common/ # 通用工具模块(工具类、常量、注解) +├── ruoyi-generator/ # 代码生成器模块 +├── ruoyi-quartz/ # 定时任务模块 +├── ruoyi-ui/ # 前端 Vue 项目 +├── sql/ # 数据库脚本 +├── bin/ # 批处理脚本(构建、运行、清理) +└── pom.xml # Maven 父 POM 配置 +``` + +### 业务模块 + +前端业务模块(位于 `ruoyi-ui/src/views/`): +- **system**: 系统管理(用户、角色、菜单、部门、岗位、字典、参数、通知) +- **monitor**: 系统监控(在线用户、操作日志、登录日志、服务监控、缓存监控、定时任务) +- **tool**: 系统工具(表单构建、代码生成、系统接口) +- **bas**: 基础数据管理 +- **in**: 入库管理 +- **out**: 出库管理 +- **stock**: 库存管理 +- **check**: 盘点管理 +- **job**: 作业管理 +- **kpi**: 绩效管理 +- **ai**: AI 功能集成 +- **search**: 搜索功能 +- **requestInterface**: 接口请求管理 +- **dashboard**: 仪表盘/数据看板 + +## 环境配置 + +### 数据库配置 + +#### 主数据库(SQL Server) +- **地址**: 172.16.2.170:1433 +- **数据库名**: FT546-wms +- **用户名**: sa +- **密码**: Flrd0914. +- **驱动**: com.microsoft.sqlserver.jdbc.SQLServerDriver + +#### 从数据库(MariaDB)- 已禁用 +- **地址**: 172.16.2.170:3307 +- **数据库名**: mydb +- **用户名**: root +- **密码**: Flrd0914. + +### Redis 配置 +- **地址**: 172.16.2.170:6379 +- **数据库索引**: 0 +- **密码**: 123456 +- **超时**: 10s + +### AI 配置 +- **提供商**: SiliconFlow (OpenAI 兼容) +- **Base URL**: https://api.siliconflow.cn +- **对话模型**: deepseek-ai/DeepSeek-V3.1 +- **嵌入模型**: Qwen/Qwen3-Embedding-8B (1024 维度) +- **向量数据库**: MariaDB (已配置但未完全启用) + +### Druid 监控 +- **访问地址**: http://localhost:8080/druid/ +- **用户名**: ruoyi +- **密码**: 123456 + +### API 文档 +- **Swagger UI**: http://localhost:8080/swagger-ui.html +- **OpenAPI JSON**: http://localhost:8080/v3/api-docs + +## 构建和运行 + +### 后端构建和运行 + +#### 方式一:使用 Maven 命令 + +```bash +# 进入项目根目录 +cd D:\workSpace\PROJECT_SPACE\FT546\FT546MWS + +# 清理并编译 +mvn clean compile + +# 打包(跳过测试) +mvn clean package -DskipTests + +# 运行 +java -jar ruoyi-admin/target/ruoyi-admin.jar + +# 或使用 JVM 参数运行 +java -Dname=ruoyi-admin.jar -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -jar ruoyi-admin/target/ruoyi-admin.jar +``` + +#### 方式二:使用批处理脚本 + +```bash +# 进入 bin 目录 +cd bin + +# 启动服务 +ry.bat +# 选择 [1] 启动 ruoyi-admin.jar + +# 停止服务 +ry.bat +# 选择 [2] 关闭 ruoyi-admin.jar + +# 重启服务 +ry.bat +# 选择 [3] 重启 ruoyi-admin.jar + +# 查看状态 +ry.bat +# 选择 [4] 查看状态 +``` + +#### 方式三:使用 IDE +1. 使用 IntelliJ IDEA 或 Eclipse 导入项目(Maven 项目) +2. 找到启动类:`com.ruoyi.RuoYiApplication`(位于 ruoyi-admin 模块) +3. 运行启动类 + +### 前端构建和运行 + +#### 开发环境 + +```bash +# 进入前端目录 +cd ruoyi-ui + +# 安装依赖(使用 npm 镜像加速) +npm install --registry=https://registry.npmmirror.com + +# 或直接安装 +npm install + +# 启动开发服务器 +npm run dev +``` + +前端服务启动后,浏览器访问:http://localhost:80 + +默认账号: +- 用户名: admin +- 密码: admin123 + +#### 生产环境构建 + +```bash +# 构建测试环境 +npm run build:stage + +# 构建生产环境 +npm run build:prod +``` + +构建产物将输出到 `ruoyi-ui/dist` 目录。 + +#### 使用批处理脚本 + +```bash +# 进入前端 bin 目录 +cd ruoyi-ui\bin + +# 运行前端开发服务器 +run-web.bat + +# 打包前端 +package.bat + +# 清理构建产物 +clean.bat +``` + +## 开发规范 + +### 后端开发规范 + +#### 包结构规范 +``` +com.ruoyi +├── common/ # 通用模块 +│ ├── annotation/ # 自定义注解 +│ ├── constant/ # 常量定义 +│ ├── core/ # 核心配置 +│ ├── enums/ # 枚举类 +│ ├── exception/ # 异常处理 +│ └── utils/ # 工具类 +├── framework/ # 框架核心 +│ ├── aspectj/ # 切面 +│ ├── config/ # 配置类 +│ ├── interceptor/ # 拦截器 +│ ├── security/ # 安全相关 +│ └── web/ # Web 配置 +├── system/ # 系统管理 +│ ├── controller/ # 控制器 +│ ├── domain/ # 实体类 +│ ├── mapper/ # 数据访问层 +│ └── service/ # 业务逻辑层 +│ └── impl/ # 业务实现 +└── web/ # Web 控制器(其他业务模块) +``` + +#### 代码生成规范 +项目使用代码生成器(`ruoyi-generator` 模块)快速生成 CRUD 代码: + +1. 在数据库中创建表 +2. 登录系统 → 系统工具 → 代码生成 +3. 导入表并配置生成信息 +4. 生成代码并下载 +5. 将生成的代码复制到对应模块 + +生成的代码包括: +- Java 实体类(domain) +- Mapper 接口和 XML(mapper) +- Service 接口和实现(service/impl) +- Controller 控制器(controller) +- Vue 页面(前端 views) +- API 接口定义(前端 api) + +#### 控制器规范 +- 使用 `@RestController` 注解 +- 统一返回格式:`AjaxResult`(包装 success、error、data) +- 权限控制:使用 `@PreAuthorize("@ss.hasPermi('system:user:list')")` +- 操作日志:使用 `@Log(title = "用户管理", businessType = BusinessType.INSERT)` +- 分页查询:使用 `startPage()` 方法(继承 BaseController) + +#### Service 规范 +- 接口定义在 `service` 包 +- 实现类在 `service/impl` 包 +- 使用 `@Service` 注解 +- 业务逻辑方法命名:`selectXxxList`(查询)、`insertXxx`(新增)、`updateXxx`(修改)、`deleteXxxByIds`(删除) +- 缓存注解:`@Cacheable`(查询)、`@CacheEvict`(更新/删除) + +#### Mapper 规范 +- 使用 MyBatis-Plus 注解或 XML 配置 +- XML 文件位于 `resources/mapper/` 目录 +- 继承 `BaseMapper` 接口 +- 复杂查询使用 XML 文件编写 SQL + +### 前端开发规范 + +#### 目录结构规范 +``` +src/ +├── api/ # API 接口定义 +│ ├── login.js # 登录相关 +│ ├── system/ # 系统管理 +│ ├── monitor/ # 监控模块 +│ └── ... # 其他业务模块 +├── assets/ # 静态资源 +│ ├── images/ # 图片 +│ ├── icons/ # 图标 +│ ├── logo/ # Logo +│ └── styles/ # 样式文件 +├── components/ # 公共组件 +│ ├── Pagination/ # 分页组件 +│ ├── RightToolbar/ # 工具栏 +│ ├── Editor/ # 富文本编辑器 +│ └── ... # 其他组件 +├── directive/ # 自定义指令 +├── layout/ # 布局组件 +├── plugins/ # 插件 +├── router/ # 路由配置 +├── store/ # Vuex 状态管理 +├── utils/ # 工具函数 +├── views/ # 页面组件 +│ ├── system/ # 系统管理页面 +│ ├── monitor/ # 监控页面 +│ └── ... # 其他业务页面 +├── App.vue # 根组件 +├── main.js # 入口文件 +├── permission.js # 权限控制 +└── settings.js # 全局配置 +``` + +#### 组件命名规范 +- 组件名使用 PascalCase(大驼峰) +- 文件名与组件名保持一致 +- 例如:`UserList.vue` + +#### API 调用规范 +- API 接口定义在 `src/api/` 目录 +- 使用 Axios 发送请求(已封装) +- 请求路径配置在 `.env.development` 等环境变量文件中 +- 统一使用 `request.js` 封装的请求方法 + +#### 路由规范 +- 路由配置在 `src/router/index.js` +- 使用 Vue Router 的路由懒加载 +- 需要权限的路由在路由配置中添加 `meta` 字段 +- 例如:`meta: { title: '用户管理', icon: 'user', noCache: true }` + +#### 样式规范 +- 使用 SCSS 预处理器 +- 全局样式放在 `src/assets/styles/` 目录 +- 组件样式使用 ` diff --git a/dosc/license.js b/dosc/license.js new file mode 100644 index 0000000..e8ead05 --- /dev/null +++ b/dosc/license.js @@ -0,0 +1,16 @@ +import request from '@/utils/request' + +export function activeLicense(licenseCode) { + return request({ + url: '/system/license/active', + method: 'post', + params: { licenseCode } + }) +} + +export function getLicenseInfo() { + return request({ + url: '/system/license/info', + method: 'get' + }) +} diff --git a/dosc/license/.WeDrive b/dosc/license/.WeDrive new file mode 100644 index 0000000..06d2142 --- /dev/null +++ b/dosc/license/.WeDrive @@ -0,0 +1 @@ +C:\Users\李涛\Documents\WXWork\1688851319997782\WeDrive\福莱瑞达\软件产品中心\软件产品中心共享资料\集成授权码功能\vue版本集成\授权码\license \ No newline at end of file diff --git a/dosc/license/SysLicenseController.java b/dosc/license/SysLicenseController.java new file mode 100644 index 0000000..6979a5b --- /dev/null +++ b/dosc/license/SysLicenseController.java @@ -0,0 +1,127 @@ +package com.ruoyi.web.controller.system.license; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +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.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.license.domain.SysLicense; +import com.ruoyi.license.service.ISysLicenseService; +import com.ruoyi.license.util.LicenseUtils; + +/** + * 授权码Controller + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/license") +public class SysLicenseController extends BaseController +{ + @Autowired + private ISysLicenseService sysLicenseService; + + /** + * 查询授权码列表 + */ + @PreAuthorize("@ss.hasPermi('system:license:list')") + @GetMapping("/list") + public TableDataInfo list(SysLicense sysLicense) + { + startPage(); + List list = sysLicenseService.selectSysLicenseList(sysLicense); + return getDataTable(list); + } + + /** + * 新增授权码 + */ + @PreAuthorize("@ss.hasPermi('system:license:add')") + @Log(title = "授权码", businessType = BusinessType.INSERT) + @PostMapping("/add") + public AjaxResult add(SysLicense sysLicense) + { + return toAjax(sysLicenseService.insertSysLicense(sysLicense)); + } + + /** + * 修改授权码 + */ + @PreAuthorize("@ss.hasPermi('system:license:edit')") + @Log(title = "授权码", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + public AjaxResult edit(SysLicense sysLicense) + { + return toAjax(sysLicenseService.updateSysLicense(sysLicense)); + } + + /** + * 删除授权码 + */ + @PreAuthorize("@ss.hasPermi('system:license:remove')") + @Log(title = "授权码", businessType = BusinessType.DELETE) + @PostMapping("/remove") + public AjaxResult remove(String ids) + { + return toAjax(sysLicenseService.deleteSysLicenseByIds(ids)); + } + + /** + * 激活授权码(无需登录) + */ + @Log(title = "激活授权码", businessType = BusinessType.UPDATE) + @PostMapping("/active") + public AjaxResult active(String licenseCode) + { + if (!LicenseUtils.validateFormat(licenseCode)) + { + return error("授权码格式不正确"); + } + int result = sysLicenseService.activeLicense(licenseCode); + if (result > 0) + { + return success("授权码激活成功"); + } + return error("授权码激活失败,请检查授权码是否正确或已过期"); + } + + /** + * 获取当前授权信息 + * license 未开启或无有效授权时返回 code=200 data=null,前端静默处理 + */ + @PreAuthorize("@ss.hasPermi('system:license:list')") + @GetMapping("/info") + public AjaxResult info() + { + SysLicense license = sysLicenseService.getActiveLicense(); + return AjaxResult.success(license); + } + + /** + * 生成授权码 + */ + @PreAuthorize("@ss.hasPermi('system:license:add')") + @GetMapping("/generate") + public AjaxResult generate(String type, String projectNo) + { + if (StringUtils.isEmpty(type) || StringUtils.isEmpty(projectNo)) + { + return error("授权类型和项目编号不能为空"); + } + String licenseCode = LicenseUtils.generateLicense(type, projectNo); + if (licenseCode == null) + { + return error("授权码生成失败"); + } + return AjaxResult.success("授权码生成成功", licenseCode); + } +} diff --git a/dosc/ruoyi-license/.WeDrive b/dosc/ruoyi-license/.WeDrive new file mode 100644 index 0000000..9c126ef --- /dev/null +++ b/dosc/ruoyi-license/.WeDrive @@ -0,0 +1 @@ +C:\Users\李涛\Documents\WXWork\1688851319997782\WeDrive\福莱瑞达\软件产品中心\软件产品中心共享资料\集成授权码功能\vue版本集成\授权码\ruoyi-license \ No newline at end of file diff --git a/dosc/ruoyi-license/CHANGES.md b/dosc/ruoyi-license/CHANGES.md new file mode 100644 index 0000000..d6c8609 --- /dev/null +++ b/dosc/ruoyi-license/CHANGES.md @@ -0,0 +1,270 @@ +# 授权码模块集成改动说明 + +> 本文档记录引入 `ruoyi-license` 授权码模块时,对原有项目文件的所有改动(不含 `ruoyi-license` 模块本身及 `SysLicenseController`)。 + +--- + +## 1. 根模块 `pom.xml` + +**文件路径:** `wms/pom.xml` + +**改动内容:** + +1. `` 中注册 `ruoyi-license` 子模块: + +```xml + + ruoyi-admin + ruoyi-framework + ruoyi-system + ruoyi-quartz + ruoyi-generator + ruoyi-common + ruoyi-license + +``` + +2. `` 中声明 `ruoyi-license` 依赖版本: + +```xml + + + com.ruoyi + ruoyi-license + ${ruoyi.version} + +``` + +--- + +## 2. `ruoyi-admin/pom.xml` + +**文件路径:** `wms/ruoyi-admin/pom.xml` + +**改动内容:** + +引入 `ruoyi-license` 依赖,使授权拦截器和配置能被 Spring Boot 扫描加载: + +```xml + + + com.ruoyi + ruoyi-license + +``` + +--- + +## 3. `SecurityConfig.java` + +**文件路径:** `wms/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java` + +**改动内容:** + +在 Spring Security 匿名白名单中加入 `/system/license/active`,允许未登录用户调用激活授权码接口: + +```java +// 改动前 +requests.antMatchers("/login", "/register", "/captchaImage").permitAll() + +// 改动后 +requests.antMatchers("/login", "/register", "/captchaImage", "/system/license/active").permitAll() +``` + +--- + +## 4. 前端 `api/license.js`(新建) + +**文件路径:** `wms/ui/src/api/license.js` + +**改动内容:** + +新建文件,封装授权码相关接口: + +```js +import request from '@/utils/request' + +// 激活授权码(无需登录) +export function activeLicense(licenseCode) { + return request({ + url: '/system/license/active', + method: 'post', + params: { licenseCode } + }) +} + +// 查询当前授权信息(需登录) +export function getLicenseInfo() { + return request({ + url: '/system/license/info', + method: 'get' + }) +} +``` + +--- + +## 5. 登录页 `login.vue` + +**文件路径:** `wms/ui/src/views/login.vue` + +**改动内容:** + +### 5.1 模板部分 + +在登录按钮下方新增"激活授权码"按钮,以及激活弹窗: + +```html + + + 激活授权码 + + + + + + + 取 消 + 激 活 + + +``` + +### 5.2 Script 部分 + +新增 import、data 字段和方法: + +```js +// 新增 import +import { activeLicense } from "@/api/license" + +// 新增 data 字段 +licenseDialogVisible: false, +licenseCode: '', +licenseLoading: false + +// 新增方法 +openLicenseDialog() { + this.licenseCode = '' + this.licenseDialogVisible = true +}, +handleActiveLicense() { + if (!this.licenseCode.trim()) { + this.$message.warning('请输入授权码') + return + } + this.licenseLoading = true + activeLicense(this.licenseCode.trim()).then(res => { + if (res.code === 200) { + this.$message.success(res.msg || '授权码激活成功') + this.licenseDialogVisible = false + } else { + this.$message.error(res.msg || '授权码激活失败') + } + }).catch(() => { + this.$message.error('授权码激活失败') + }).finally(() => { + this.licenseLoading = false + }) +} +``` + +--- + +## 6. 顶部导航栏 `Navbar.vue` + +**文件路径:** `wms/ui/src/layout/components/Navbar.vue` + +**改动内容:** + +### 6.1 模板部分 + +在 navbar 中间插入授权到期警告条(剩余不足 30 天时显示): + +```html +
+ + 系统授权将于 {{ licenseExpireText }} 后过期,请及时联系管理员续期 +
+``` + +### 6.2 Script 部分 + +```js +// 新增 import +import { getLicenseInfo } from '@/api/license' + +// 新增 data 字段 +licenseWarning: false, +licenseExpireText: '', +licenseTimer: null + +// 新增生命周期钩子 +mounted() { + this.checkLicenseExpire() + this.licenseTimer = setInterval(() => this.checkLicenseExpire(), 60 * 1000) +}, +beforeDestroy() { + if (this.licenseTimer) clearInterval(this.licenseTimer) +}, + +// 新增方法 +checkLicenseExpire() { + getLicenseInfo().then(res => { + if (res.code === 200 && res.data && res.data.expireTime) { + const expireTime = new Date(res.data.expireTime).getTime() + const now = Date.now() + const diffMs = expireTime - now + const diffDays = Math.ceil(diffMs / (1000 * 60 * 60 * 24)) + if (diffMs > 0 && diffDays <= 30) { + this.licenseWarning = true + if (diffMs < 1000 * 60 * 60 * 24) { + const hours = Math.floor(diffMs / (1000 * 60 * 60)) + const minutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60)) + this.licenseExpireText = hours > 0 ? `${hours} 小时 ${minutes} 分钟` : `${minutes} 分钟` + } else if (diffDays < 7) { + this.licenseExpireText = diffDays + ' 天' + } else { + this.licenseExpireText = Math.ceil(diffDays / 7) + ' 周' + } + } + } + }).catch(() => {}) +} +``` + +### 6.3 样式部分 + +```scss +.license-warning { + position: absolute; + left: 50%; + transform: translateX(-50%); + top: 0; + height: 50px; + line-height: 50px; + font-size: 13px; + color: #e6a23c; + font-weight: 500; + pointer-events: none; + i { margin-right: 4px; } +} +``` + +--- + +## 改动文件汇总 + +| 文件 | 类型 | 说明 | +|---|---|---| +| `wms/pom.xml` | 修改 | 注册模块 + 声明依赖版本 | +| `wms/ruoyi-admin/pom.xml` | 修改 | 引入 ruoyi-license 依赖 | +| `ruoyi-framework/.../SecurityConfig.java` | 修改 | 白名单加入激活授权码接口 | +| `ui/src/api/license.js` | 新建 | 封装激活和查询授权信息接口 | +| `ui/src/views/login.vue` | 修改 | 新增激活授权码按钮和弹窗 | +| `ui/src/layout/components/Navbar.vue` | 修改 | 新增授权到期倒计时警告条 | diff --git a/dosc/ruoyi-license/DEPLOYMENT_CHECKLIST.md b/dosc/ruoyi-license/DEPLOYMENT_CHECKLIST.md new file mode 100644 index 0000000..cac7b0e --- /dev/null +++ b/dosc/ruoyi-license/DEPLOYMENT_CHECKLIST.md @@ -0,0 +1,250 @@ +# 授权码模块部署检查清单 + +## 📋 部署前检查 + +### 1. 文件完整性检查 +- [ ] ruoyi-license 模块目录存在 +- [ ] pom.xml 已添加 license 模块 +- [ ] ruoyi-admin/pom.xml 已添加 license 依赖 +- [ ] SysLicenseController.java 已创建 +- [ ] license.html 和 active.html 已创建 +- [ ] login.html 和 login.js 已修改 +- [ ] sys_license.sql 脚本已准备 + +### 2. 数据库准备 +- [ ] 创建 sys_license 表 +- [ ] 插入授权管理菜单数据 +- [ ] 验证表结构正确 +- [ ] 检查菜单权限配置 + +### 3. 代码配置 +- [ ] 修改 LicenseUtils.java 中的密钥(生产环境必须) +- [ ] 确认拦截器路径配置正确 +- [ ] 确认定时任务cron表达式 +- [ ] 启动类添加 @EnableScheduling 注解 + +## 🔧 部署步骤 + +### 步骤1: 执行数据库脚本 +```bash +mysql -u root -p your_database < sql/sys_license.sql +``` +- [ ] 执行成功 +- [ ] 表创建成功 +- [ ] 菜单数据插入成功 + +### 步骤2: 修改启动类 +```java +@SpringBootApplication +@EnableScheduling // 添加此注解 +public class RuoYiApplication { + // ... +} +``` +- [ ] 注解已添加 + +### 步骤3: 编译项目 +```bash +mvn clean install +``` +- [ ] 编译成功 +- [ ] 无错误信息 +- [ ] JAR包生成 + +### 步骤4: 启动应用 +```bash +java -jar ruoyi-admin.jar +``` +- [ ] 启动成功 +- [ ] 无异常日志 +- [ ] 端口正常监听 + +### 步骤5: 生成授权码 +**方式A: 使用独立工具** +```bash +java com.ruoyi.license.util.LicenseGenerator +``` +- [ ] 工具运行成功 +- [ ] 授权码生成成功 +- [ ] 授权码已保存 + +**方式B: 使用系统界面** +- [ ] 登录系统 +- [ ] 访问授权管理 +- [ ] 点击生成授权码 +- [ ] 输入天数并生成 + +### 步骤6: 激活授权码 +- [ ] 访问登录页 +- [ ] 点击"激活授权码" +- [ ] 输入授权码 +- [ ] 激活成功 + +## ✅ 功能测试 + +### 测试1: 授权码生成 +- [ ] 系统界面生成授权码成功 +- [ ] 独立工具生成授权码成功 +- [ ] 授权码格式正确 + +### 测试2: 授权码激活 +- [ ] 登录页激活成功 +- [ ] 系统内激活成功 +- [ ] 数据库记录正确 + +### 测试3: 授权验证 +- [ ] 有效授权可正常登录 +- [ ] 无授权无法登录 +- [ ] 过期授权无法登录 + +### 测试4: 授权拦截 +- [ ] 未授权访问被拦截 +- [ ] 有效授权可正常访问 +- [ ] 静态资源不被拦截 + +### 测试5: 定时检查 +- [ ] 定时任务正常执行 +- [ ] 授权过期自动更新状态 +- [ ] 在线用户被踢出 + +### 测试6: 授权管理 +- [ ] 授权列表查询正常 +- [ ] 授权信息显示正确 +- [ ] 授权删除功能正常 + +## 🔍 问题排查 + +### 问题1: 编译失败 +**检查项:** +- [ ] Maven依赖是否正确 +- [ ] JDK版本是否匹配 +- [ ] pom.xml配置是否正确 + +**解决方案:** +```bash +mvn clean +mvn dependency:resolve +mvn install +``` + +### 问题2: 启动失败 +**检查项:** +- [ ] 数据库连接是否正常 +- [ ] 端口是否被占用 +- [ ] 配置文件是否正确 + +**解决方案:** +- 检查 application.yml 配置 +- 查看启动日志错误信息 +- 确认数据库表已创建 + +### 问题3: 无法激活授权码 +**检查项:** +- [ ] 授权码格式是否正确 +- [ ] 授权码是否已过期 +- [ ] 密钥是否一致 + +**解决方案:** +- 重新生成授权码 +- 检查 LicenseUtils 密钥配置 +- 查看后台错误日志 + +### 问题4: 授权验证不生效 +**检查项:** +- [ ] 拦截器是否注册 +- [ ] 数据库授权记录是否正确 +- [ ] 定时任务是否执行 + +**解决方案:** +- 检查 LicenseConfig 配置 +- 验证数据库 status 字段 +- 确认 @EnableScheduling 已添加 + +### 问题5: 在线用户未被踢出 +**检查项:** +- [ ] SessionDAO 是否注入 +- [ ] 定时任务是否执行 +- [ ] Shiro配置是否正确 + +**解决方案:** +- 检查 LicenseCheckTask 日志 +- 验证 SessionDAO bean +- 重启应用服务器 + +## 📊 监控指标 + +### 运行时监控 +- [ ] 授权状态正常 +- [ ] 定时任务执行正常 +- [ ] 无异常日志 +- [ ] 内存使用正常 +- [ ] CPU使用正常 + +### 业务监控 +- [ ] 授权激活次数 +- [ ] 授权过期提醒 +- [ ] 用户登录成功率 +- [ ] 授权拦截次数 + +## 🔐 安全检查 + +### 配置安全 +- [ ] 生产环境已修改默认密钥 +- [ ] 数据库密码已加密 +- [ ] 授权码传输使用HTTPS +- [ ] 敏感日志已脱敏 + +### 权限安全 +- [ ] 授权管理菜单仅管理员可见 +- [ ] 授权激活操作有日志记录 +- [ ] 授权码生成有权限控制 +- [ ] 数据库访问有权限限制 + +### 数据安全 +- [ ] 授权码加密存储 +- [ ] 定期备份授权数据 +- [ ] 授权日志完整保存 +- [ ] 敏感信息不输出到日志 + +## 📝 上线清单 + +### 上线前 +- [ ] 所有测试通过 +- [ ] 代码已提交版本库 +- [ ] 数据库脚本已准备 +- [ ] 部署文档已编写 +- [ ] 回滚方案已准备 + +### 上线中 +- [ ] 备份现有数据 +- [ ] 执行数据库脚本 +- [ ] 部署新版本代码 +- [ ] 生成初始授权码 +- [ ] 激活授权码 + +### 上线后 +- [ ] 验证功能正常 +- [ ] 检查日志无异常 +- [ ] 监控系统运行状态 +- [ ] 通知相关人员 +- [ ] 更新运维文档 + +## 📞 应急联系 + +### 技术支持 +- 开发负责人: ___________ +- 运维负责人: ___________ +- 数据库管理员: ___________ + +### 应急预案 +1. 授权失效 -> 立即激活新授权码 +2. 系统无法登录 -> 检查授权状态 +3. 数据丢失 -> 从备份恢复 +4. 性能问题 -> 调整定时任务频率 + +--- + +**检查人**: ___________ +**检查日期**: ___________ +**部署环境**: [ ] 开发 [ ] 测试 [ ] 生产 +**部署状态**: [ ] 成功 [ ] 失败 [ ] 部分成功 diff --git a/dosc/ruoyi-license/INTEGRATION.md b/dosc/ruoyi-license/INTEGRATION.md new file mode 100644 index 0000000..1b8199b --- /dev/null +++ b/dosc/ruoyi-license/INTEGRATION.md @@ -0,0 +1,231 @@ +# RuoYi 授权码模块集成指南 + +## 一、模块说明 + +本授权码模块已完成开发,包含以下文件: + +``` +ruoyi-license/ # 授权模块(独立模块) +├── src/main/java/com/ruoyi/license/ +│ ├── config/ +│ │ └── LicenseConfig.java # 拦截器配置 +│ ├── domain/ +│ │ └── SysLicense.java # 授权实体 +│ ├── interceptor/ +│ │ └── LicenseInterceptor.java # 授权拦截器 +│ ├── mapper/ +│ │ └── SysLicenseMapper.java # 数据访问接口 +│ ├── service/ +│ │ ├── ISysLicenseService.java # 服务接口 +│ │ └── impl/ +│ │ └── SysLicenseServiceImpl.java # 服务实现 +│ ├── task/ +│ │ └── LicenseCheckTask.java # 定时检查任务 +│ └── util/ +│ ├── LicenseUtils.java # 授权工具类 +│ └── LicenseGenerator.java # 授权码生成器 +├── src/main/resources/mapper/license/ +│ └── SysLicenseMapper.xml # MyBatis映射 +├── pom.xml # 模块依赖 +└── README.md # 使用说明 + +sql/ +└── sys_license.sql # 数据库脚本 + +ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/license/ +└── SysLicenseController.java # 授权控制器 + +ruoyi-admin/src/main/resources/templates/system/license/ +├── license.html # 授权列表页 +└── active.html # 激活页面 + +修改的文件: +- pom.xml # 添加license模块 +- ruoyi-admin/pom.xml # 添加license依赖 +- login.html # 添加激活入口 +- login.js # 添加激活功能 +``` + +## 二、部署步骤 + +### 1. 执行数据库脚本 + +```bash +# 在MySQL中执行 +mysql -u root -p your_database < sql/sys_license.sql +``` + +或手动执行 `sql/sys_license.sql` 中的SQL语句。 + +### 2. 启用定时任务 + +在启动类上添加 `@EnableScheduling` 注解: + +```java +@SpringBootApplication +@EnableScheduling // 添加此注解 +public class RuoYiApplication { + public static void main(String[] args) { + SpringApplication.run(RuoYiApplication.class, args); + } +} +``` + +### 3. 编译项目 + +```bash +cd d:\fortucky\project\RuoYi-master +mvn clean install +``` + +### 4. 生成授权码 + +**方式一:使用独立工具生成** +```bash +cd ruoyi-license/src/main/java +javac com/ruoyi/license/util/LicenseUtils.java +javac com/ruoyi/license/util/LicenseGenerator.java +java com.ruoyi.license.util.LicenseGenerator +``` + +**方式二:启动系统后在界面生成** +- 登录系统 +- 进入"系统管理 -> 授权管理" +- 点击"生成授权码"按钮 + +### 5. 激活授权码 + +**首次激活(登录页):** +1. 访问登录页 +2. 点击"激活授权码"链接 +3. 输入生成的授权码 +4. 提交激活 + +**系统内激活:** +1. 登录系统(需要先有有效授权) +2. 进入"系统管理 -> 授权管理" +3. 点击"激活授权码" +4. 输入新的授权码 + +## 三、功能验证 + +### 1. 验证授权拦截 + +- 未激活授权码时,访问任何页面应跳转到登录页并提示"授权已过期" +- 激活授权码后,可正常访问系统 + +### 2. 验证定时检查 + +- 修改数据库中授权码的 `expire_time` 为过去时间 +- 等待5分钟(或重启系统) +- 在线用户应被强制退出 +- 尝试登录应提示授权过期 + +### 3. 验证授权管理 + +- 访问"系统管理 -> 授权管理" +- 查看授权列表 +- 生成新授权码 +- 激活授权码 +- 删除过期授权 + +## 四、复用到其他项目 + +### 方式一:Maven依赖(推荐) + +1. 将 `ruoyi-license` 模块复制到目标项目 +2. 在父pom.xml添加模块声明 +3. 在需要的模块添加依赖 +4. 执行数据库脚本 +5. 复制Controller和前端页面 + +### 方式二:JAR包依赖 + +1. 打包license模块: +```bash +cd ruoyi-license +mvn clean package +``` + +2. 安装到本地仓库: +```bash +mvn install:install-file -Dfile=target/ruoyi-license-4.8.2.jar \ + -DgroupId=com.ruoyi -DartifactId=ruoyi-license \ + -Dversion=4.8.2 -Dpackaging=jar +``` + +3. 在目标项目添加依赖: +```xml + + com.ruoyi + ruoyi-license + 4.8.2 + +``` + +## 五、配置说明 + +### 1. 修改密钥(重要) + +生产环境必须修改默认密钥: + +```java +// LicenseUtils.java +private static final String SECRET_KEY = "YourCustomKey123"; // 改为16位自定义密钥 +``` + +### 2. 调整检查频率 + +```java +// LicenseCheckTask.java +@Scheduled(cron = "0 */5 * * * ?") // 每5分钟,可根据需要调整 +``` + +### 3. 自定义拦截路径 + +```java +// LicenseConfig.java +.excludePathPatterns( + "/login", + "/your-path/**" // 添加需要排除的路径 +) +``` + +## 六、注意事项 + +1. **首次部署**:必须先生成并激活授权码,否则无法登录 +2. **时间同步**:确保服务器时间准确,避免授权判断错误 +3. **密钥安全**:生产环境务必修改默认密钥 +4. **数据备份**:定期备份 `sys_license` 表数据 +5. **权限控制**:授权管理菜单仅授予超级管理员 + +## 七、故障排查 + +### 问题1:无法激活授权码 +- 检查授权码格式是否正确 +- 检查授权码是否已过期 +- 查看后台日志错误信息 + +### 问题2:授权有效但仍被拦截 +- 检查数据库中授权状态是否为"1" +- 检查 `expire_time` 是否大于当前时间 +- 重启应用服务器 + +### 问题3:定时任务不执行 +- 确认启动类添加了 `@EnableScheduling` +- 检查日志是否有定时任务执行记录 + +### 问题4:在线用户未被踢出 +- 检查 `SessionDAO` 是否正确注入 +- 查看定时任务是否正常执行 +- 检查Shiro配置是否正确 + +## 八、技术支持 + +如遇到问题,请提供以下信息: +1. 错误日志 +2. 数据库授权记录 +3. 系统环境信息 +4. 操作步骤 + +联系方式:参考RuoYi官方文档 diff --git a/dosc/ruoyi-license/LICENSE_FILTER_CONFIG.md b/dosc/ruoyi-license/LICENSE_FILTER_CONFIG.md new file mode 100644 index 0000000..7a3ba06 --- /dev/null +++ b/dosc/ruoyi-license/LICENSE_FILTER_CONFIG.md @@ -0,0 +1,168 @@ +# 授权码全局拦截配置说明 + +## 功能说明 + +通过自定义 Shiro Filter,实现授权码失效时,**所有接口**(包括 `anon` 匿名访问的接口)都无法访问。 + +## 实现原理 + +1. 创建 `LicenseValidateFilter` 继承 `AccessControlFilter` +2. 在 Shiro 过滤链的**最前面**添加此过滤器 +3. 所有请求都会先经过授权码验证,验证失败则拒绝访问 + +## 已完成的修改 + +### 1. 新增文件 +- `ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/web/filter/license/LicenseValidateFilter.java` + +### 2. 修改文件 +- `ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java` + - 导入 `LicenseValidateFilter` + - 注册过滤器:`filters.put("licenseValidate", licenseValidateFilter())` + - 添加到过滤链:`filterChainDefinitionMap.put("/**", "licenseValidate,user,kickout,onlineSession,syncOnlineSession")` + +## 白名单配置 + +以下路径即使授权失效也可以访问(必要的登录和静态资源): + +```java +private static final String[] WHITE_LIST = { + "/login", // 登录页 + "/captcha/captchaImage", // 验证码 + "/css/", // 样式文件 + "/js/", // 脚本文件 + "/img/", // 图片资源 + "/fonts/", // 字体文件 + "/ajax/", // Ajax资源 + "/ruoyi/", // 若依资源 + "/favicon.ico", // 网站图标 + "/system/license/active" // 授权激活页面(必须放行) +}; +``` + +## 自定义白名单 + +如果需要添加其他路径到白名单,修改 `LicenseValidateFilter.java`: + +```java +private static final String[] WHITE_LIST = { + // ... 原有配置 + "/your-custom-path/**", // 添加你的自定义路径 +}; +``` + +## 拦截效果 + +### 授权有效时 +- 所有接口正常访问(包括 `/board/**`、`/agv/api/**` 等 anon 接口) + +### 授权失效时 +- **普通请求**:重定向到 `/login?license=expired` +- **Ajax请求**:返回 JSON `{"code":401,"msg":"授权已过期,请联系管理员激活授权码"}` +- **白名单路径**:仍可访问(用于激活授权码) + +## 测试步骤 + +### 1. 启用授权功能 +在 `application.yml` 中配置: +```yaml +license: + enabled: true +``` + +### 2. 配置项目编号 +在数据库 `sys_config` 表中添加: +```sql +INSERT INTO sys_config (config_name, config_key, config_value, config_type, create_by, create_time, remark) +VALUES ('项目编号', 'fortucky.project.no', 'FT507', 'Y', 'admin', NOW(), '用于授权码验证'); +``` + +### 3. 测试授权失效场景 + +**方式一:不激活授权码** +- 启动系统 +- 访问 `/board/**` 接口 +- 预期:被拦截,重定向到登录页 + +**方式二:授权码过期** +- 生成5分钟测试授权码并激活 +- 等待5分钟后访问 `/board/**` 接口 +- 预期:被拦截 + +### 4. 测试授权有效场景 +- 生成并激活有效授权码 +- 访问 `/board/**` 接口 +- 预期:正常访问 + +## 注意事项 + +1. **白名单必须包含授权激活页面** + - `/system/license/active` 必须在白名单中 + - 否则授权失效后无法激活新授权码 + +2. **静态资源必须放行** + - CSS、JS、图片等资源必须在白名单 + - 否则登录页面无法正常显示 + +3. **过滤器顺序很重要** + - `licenseValidate` 必须在最前面 + - 确保所有请求都先经过授权验证 + +4. **开发环境可关闭授权** + ```yaml + license: + enabled: false # 开发时可关闭 + ``` + +## 与原有拦截器的区别 + +### 原有 LicenseInterceptor(Spring MVC 拦截器) +- 在 Spring MVC 层拦截 +- 只拦截进入 Controller 的请求 +- 无法拦截 Shiro 已放行的 `anon` 接口 + +### 新增 LicenseValidateFilter(Shiro 过滤器) +- 在 Shiro 层拦截 +- 拦截所有请求(包括 `anon` 接口) +- 优先级高于 Shiro 的其他过滤器 + +## 建议 + +1. **保留两个拦截器** + - `LicenseValidateFilter`:全局拦截(包括 anon 接口) + - `LicenseInterceptor`:作为二次验证(可选) + +2. **生产环境必须启用** + ```yaml + license: + enabled: true + ``` + +3. **定期检查白名单** + - 确保白名单路径最小化 + - 避免过度放行 + +## 故障排查 + +### 问题1:所有请求都被拦截 +- 检查 `license.enabled` 是否为 `true` +- 检查是否有有效授权码 +- 查看后台日志 `[授权验证]` 相关信息 + +### 问题2:anon 接口仍可访问 +- 检查过滤器是否注册:`filters.put("licenseValidate", ...)` +- 检查过滤链配置:`"licenseValidate,user,..."` +- 确认 `licenseValidate` 在最前面 + +### 问题3:无法激活授权码 +- 检查 `/system/license/active` 是否在白名单 +- 检查白名单匹配逻辑是否正确 + +## 完成标志 + +✅ 授权失效时,`/board/**` 接口无法访问 +✅ 授权失效时,`/agv/api/**` 接口无法访问 +✅ 授权失效时,仍可访问登录页和激活页 +✅ 授权有效时,所有接口正常访问 +✅ Ajax 请求返回 JSON 错误信息 +✅ 普通请求重定向到登录页 diff --git a/dosc/ruoyi-license/README.md b/dosc/ruoyi-license/README.md new file mode 100644 index 0000000..5cfa495 --- /dev/null +++ b/dosc/ruoyi-license/README.md @@ -0,0 +1,193 @@ +# RuoYi 授权码模块 + +## 模块简介 + +ruoyi-license 是一个独立的授权码管理模块,用于控制系统的使用期限。当授权码过期后,系统将无法登录,已登录用户会被强制退出。 + +## 功能特性 + +- ✅ 授权码加密存储 +- ✅ 登录时验证授权有效性 +- ✅ 定时检查授权状态(每5分钟) +- ✅ 授权过期自动踢出在线用户 +- ✅ 系统管理界面查看/激活授权 +- ✅ 登录页面激活授权码 +- ✅ 授权码生成工具 +- ✅ 独立模块,方便其他项目复用 + +## 快速开始 + +### 1. 执行数据库脚本 + +```sql +-- 执行 sql/sys_license.sql 创建授权表和菜单 +``` + +### 2. 添加模块依赖 + +在需要使用授权功能的项目中,添加依赖: + +```xml + + com.ruoyi + ruoyi-license + 4.8.2 + +``` + +### 3. 配置包扫描 + +确保Spring能扫描到授权模块的包: + +```java +@SpringBootApplication +@ComponentScan(basePackages = {"com.ruoyi"}) +public class RuoYiApplication { + // ... +} +``` + +### 4. 生成授权码 + +访问系统管理 -> 授权管理,点击"生成授权码"按钮,输入授权天数(如365天),系统会生成加密的授权码。 + +### 5. 激活授权码 + +**方式一:登录页激活** +- 在登录页面点击"激活授权码"链接 +- 输入授权码并提交 + +**方式二:系统内激活** +- 登录系统后,进入"系统管理 -> 授权管理" +- 点击"激活授权码"按钮 +- 输入授权码并提交 + +## 核心类说明 + +### 1. 实体类 +- `SysLicense`: 授权码实体,包含授权码、开始时间、结束时间、状态等信息 + +### 2. 工具类 +- `LicenseUtils`: 授权码工具类 + - `generateLicense()`: 生成授权码 + - `encrypt()`: 加密数据 + - `decrypt()`: 解密数据 + - `validateFormat()`: 验证授权码格式 + +### 3. 服务类 +- `ISysLicenseService`: 授权服务接口 + - `activeLicense()`: 激活授权码 + - `checkLicenseValid()`: 检查授权是否有效 + - `getActiveLicense()`: 获取当前有效授权 + +### 4. 拦截器 +- `LicenseInterceptor`: 授权拦截器,在每次请求时验证授权有效性 + +### 5. 定时任务 +- `LicenseCheckTask`: 每5分钟检查授权状态,过期自动踢出在线用户 + +## 授权码格式 + +授权码采用AES加密,格式为: +``` +加密(开始时间戳|结束时间戳) +``` + +示例: +``` +原始数据: 1704067200000|1735689600000 +加密后: Xj8K9mN2pQ5rT7vW1yZ3aB4cD6eF8gH0iJ2kL4mN6oP8qR0sT2uV4wX6yZ8 +``` + +## 集成到其他项目 + +### 步骤1:复制模块 +将 `ruoyi-license` 文件夹复制到目标项目根目录 + +### 步骤2:修改pom.xml +在父pom.xml中添加: +```xml + + ruoyi-license + + + + + + com.ruoyi + ruoyi-license + ${project.version} + + + +``` + +### 步骤3:添加依赖 +在启动模块的pom.xml中添加: +```xml + + com.ruoyi + ruoyi-license + +``` + +### 步骤4:执行SQL脚本 +执行 `sql/sys_license.sql` 创建数据库表 + +### 步骤5:配置Controller +将 `SysLicenseController.java` 复制到项目的controller包中 + +### 步骤6:配置前端页面 +将 `templates/system/license/` 目录复制到项目的templates目录 + +### 步骤7:修改登录页面 +参考 `login.html` 和 `login.js` 的修改,添加授权码激活入口 + +## 自定义配置 + +### 修改密钥 +编辑 `LicenseUtils.java`: +```java +private static final String SECRET_KEY = "YourSecretKey123"; // 16位密钥 +``` + +### 修改检查频率 +编辑 `LicenseCheckTask.java`: +```java +@Scheduled(cron = "0 */10 * * * ?") // 改为每10分钟检查 +``` + +### 自定义拦截规则 +编辑 `LicenseConfig.java`,添加或排除拦截路径: +```java +.excludePathPatterns( + "/login", + "/your-custom-path/**" +) +``` + +## 注意事项 + +1. **密钥安全**:生产环境务必修改默认密钥 +2. **时间同步**:确保服务器时间准确 +3. **数据备份**:定期备份授权表数据 +4. **权限控制**:授权管理菜单仅授予管理员 +5. **测试环境**:建议先在测试环境验证功能 + +## 常见问题 + +**Q: 授权码激活失败?** +A: 检查授权码格式是否正确,是否已过期 + +**Q: 如何延长授权期限?** +A: 生成新的授权码并激活即可 + +**Q: 授权过期后如何恢复?** +A: 在登录页点击"激活授权码",输入新的授权码 + +**Q: 可以同时激活多个授权码吗?** +A: 系统只使用最新激活且未过期的授权码 + +## 技术支持 + +如有问题,请联系技术支持或查看RuoYi官方文档。 diff --git a/dosc/ruoyi-license/SUMMARY.md b/dosc/ruoyi-license/SUMMARY.md new file mode 100644 index 0000000..dc7e368 --- /dev/null +++ b/dosc/ruoyi-license/SUMMARY.md @@ -0,0 +1,239 @@ +# RuoYi 授权码模块 - 项目总结 + +## 📦 已完成的工作 + +### 1. 核心模块开发 ✅ + +**ruoyi-license 独立模块** +- ✅ Maven模块配置 (pom.xml) +- ✅ 授权实体类 (SysLicense.java) +- ✅ 数据访问层 (SysLicenseMapper.java + XML) +- ✅ 业务逻辑层 (ISysLicenseService.java + Impl) +- ✅ 授权工具类 (LicenseUtils.java) +- ✅ 授权拦截器 (LicenseInterceptor.java) +- ✅ 拦截器配置 (LicenseConfig.java) +- ✅ 定时检查任务 (LicenseCheckTask.java) +- ✅ 授权码生成器 (LicenseGenerator.java) +- ✅ 测试工具 (LicenseTest.java) + +### 2. 控制器和前端 ✅ + +**后端控制器** +- ✅ SysLicenseController.java (授权管理控制器) + - 授权列表查询 + - 授权码激活 + - 授权码生成 + - 授权信息查看 + - 授权删除 + +**前端页面** +- ✅ license.html (授权列表页) +- ✅ active.html (激活页面) +- ✅ login.html (添加激活入口) +- ✅ login.js (添加激活功能) + +### 3. 数据库脚本 ✅ + +- ✅ sys_license.sql + - 授权表结构 + - 菜单权限配置 + +### 4. 项目集成 ✅ + +- ✅ 主pom.xml (添加license模块) +- ✅ ruoyi-admin/pom.xml (添加license依赖) + +### 5. 文档编写 ✅ + +- ✅ README.md (使用说明) +- ✅ INTEGRATION.md (集成指南) + +## 🎯 功能特性 + +### 核心功能 +1. **授权码加密存储** - AES加密,安全可靠 +2. **登录验证** - 登录时自动验证授权有效性 +3. **拦截器保护** - 所有请求都经过授权验证 +4. **定时检查** - 每5分钟自动检查授权状态 +5. **自动踢出** - 授权过期自动踢出所有在线用户 +6. **管理界面** - 完整的授权管理功能 +7. **登录页激活** - 无需登录即可激活授权码 +8. **授权码生成** - 内置生成工具,支持自定义天数 + +### 技术亮点 +- 🔒 AES加密算法保护授权码 +- 🔄 Spring拦截器实现全局授权验证 +- ⏰ Spring定时任务自动检查授权 +- 🎨 完整的前后端交互界面 +- 📦 独立模块设计,方便复用 +- 🛠️ 提供测试工具和生成工具 + +## 📂 文件清单 + +``` +ruoyi-license/ +├── src/main/java/com/ruoyi/license/ +│ ├── config/ +│ │ └── LicenseConfig.java (拦截器配置) +│ ├── domain/ +│ │ └── SysLicense.java (授权实体) +│ ├── interceptor/ +│ │ └── LicenseInterceptor.java (授权拦截器) +│ ├── mapper/ +│ │ └── SysLicenseMapper.java (Mapper接口) +│ ├── service/ +│ │ ├── ISysLicenseService.java (服务接口) +│ │ └── impl/ +│ │ └── SysLicenseServiceImpl.java (服务实现) +│ ├── task/ +│ │ └── LicenseCheckTask.java (定时任务) +│ └── util/ +│ ├── LicenseUtils.java (工具类) +│ ├── LicenseGenerator.java (生成器) +│ └── LicenseTest.java (测试工具) +├── src/main/resources/mapper/license/ +│ └── SysLicenseMapper.xml (MyBatis映射) +├── pom.xml (模块配置) +├── README.md (使用说明) +└── INTEGRATION.md (集成指南) + +sql/ +└── sys_license.sql (数据库脚本) + +ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/license/ +└── SysLicenseController.java (控制器) + +ruoyi-admin/src/main/resources/templates/system/license/ +├── license.html (列表页) +└── active.html (激活页) + +修改的文件: +├── pom.xml (添加模块) +├── ruoyi-admin/pom.xml (添加依赖) +├── ruoyi-admin/src/main/resources/templates/login.html +└── ruoyi-admin/src/main/resources/static/ruoyi/login.js +``` + +## 🚀 快速开始 + +### 1. 执行数据库脚本 +```sql +source sql/sys_license.sql; +``` + +### 2. 启用定时任务 +在 RuoYiApplication.java 添加 @EnableScheduling + +### 3. 编译项目 +```bash +mvn clean install +``` + +### 4. 生成授权码 +运行 LicenseGenerator.java 或在系统界面生成 + +### 5. 激活授权码 +登录页点击"激活授权码"输入授权码 + +## 🔧 使用场景 + +### 场景1:软件交付 +- 开发完成后生成授权码 +- 交付给客户时提供授权码 +- 客户激活后可使用指定期限 + +### 场景2:试用版本 +- 生成30天试用授权码 +- 客户试用满意后购买正式授权 +- 激活正式授权码延长使用期限 + +### 场景3:订阅服务 +- 按年生成授权码 +- 到期前提醒客户续费 +- 续费后激活新授权码 + +### 场景4:多项目复用 +- 将license模块复制到其他项目 +- 修改密钥和配置 +- 快速实现授权功能 + +## ⚙️ 自定义配置 + +### 修改密钥(必须) +```java +// LicenseUtils.java +private static final String SECRET_KEY = "YourKey16Chars!!"; +``` + +### 调整检查频率 +```java +// LicenseCheckTask.java +@Scheduled(cron = "0 */10 * * * ?") // 改为10分钟 +``` + +### 自定义拦截路径 +```java +// LicenseConfig.java +.excludePathPatterns("/api/**", "/public/**") +``` + +## 📊 数据库表结构 + +```sql +sys_license (授权表) +├── license_id (授权ID - 主键) +├── license_code (授权码 - 加密存储) +├── start_time (开始时间) +├── expire_time (结束时间) +├── status (状态: 0未激活 1已激活 2已过期) +├── active_time (激活时间) +├── active_by (激活人) +├── create_by (创建者) +├── create_time (创建时间) +├── update_by (更新者) +├── update_time (更新时间) +└── remark (备注) +``` + +## 🔐 安全建议 + +1. **生产环境必须修改默认密钥** +2. **授权码通过安全渠道传递** +3. **定期备份授权表数据** +4. **限制授权管理菜单权限** +5. **监控授权激活日志** + +## 📝 后续优化建议 + +1. **硬件绑定** - 绑定服务器MAC地址或CPU序列号 +2. **在线验证** - 连接授权服务器在线验证 +3. **授权分级** - 不同授权码对应不同功能权限 +4. **自动续费** - 集成支付接口自动续费 +5. **授权统计** - 统计授权使用情况和到期提醒 + +## ✅ 测试清单 + +- [ ] 数据库表创建成功 +- [ ] 菜单权限配置正确 +- [ ] 授权码生成功能正常 +- [ ] 授权码加密解密正确 +- [ ] 登录页激活功能正常 +- [ ] 系统内激活功能正常 +- [ ] 授权拦截器生效 +- [ ] 定时任务执行正常 +- [ ] 授权过期自动踢出 +- [ ] 授权列表查询正常 + +## 📞 技术支持 + +如有问题,请查看: +1. README.md - 使用说明 +2. INTEGRATION.md - 集成指南 +3. RuoYi官方文档 + +--- + +**开发完成时间**: 2024 +**模块版本**: 1.0.0 +**适用框架**: RuoYi v4.8.2 +**技术栈**: SpringBoot + MyBatis + Shiro + Thymeleaf diff --git a/dosc/ruoyi-license/pom.xml b/dosc/ruoyi-license/pom.xml new file mode 100644 index 0000000..d287653 --- /dev/null +++ b/dosc/ruoyi-license/pom.xml @@ -0,0 +1,39 @@ + + + + ruoyi + com.ruoyi + 3.8.9 + + 4.0.0 + + ruoyi-license + + + 授权码管理模块 + + + + + + + com.ruoyi + ruoyi-common + + + + + com.ruoyi + ruoyi-system + + + + + org.springframework.boot + spring-boot-starter-web + + + + diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/config/.WeDrive b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/config/.WeDrive new file mode 100644 index 0000000..c216a2c --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/config/.WeDrive @@ -0,0 +1 @@ +C:\Users\李涛\Documents\WXWork\1688851319997782\WeDrive\福莱瑞达\软件产品中心\软件产品中心共享资料\集成授权码功能\vue版本集成\授权码\ruoyi-license\src\main\java\com\ruoyi\license\config \ No newline at end of file diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/config/LicenseConfig.java b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/config/LicenseConfig.java new file mode 100644 index 0000000..2c4a18a --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/config/LicenseConfig.java @@ -0,0 +1,61 @@ +package com.ruoyi.license.config; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import com.ruoyi.framework.config.properties.PermitAllUrlProperties; +import com.ruoyi.license.interceptor.LicenseInterceptor; + +/** + * 授权模块配置 + * + * @author ruoyi + */ +@Configuration +public class LicenseConfig implements WebMvcConfigurer +{ + @Autowired + private LicenseInterceptor licenseInterceptor; + + @Autowired + private PermitAllUrlProperties permitAllUrl; + + @Value("${license.enabled:false}") + private boolean licenseEnabled; + + private static final List BASE_EXCLUDE = Arrays.asList( + "/login", + "/logout", + "/register", + "/captchaImage", + "/system/license/active", + "/swagger-ui.html", + "/swagger-resources/**", + "/webjars/**", + "/*/api-docs", + "/druid/**", + "/*.html", + "/**/*.html", + "/**/*.css", + "/**/*.js", + "/profile/**" + ); + + @Override + public void addInterceptors(InterceptorRegistry registry) + { + if (licenseEnabled) + { + List excludeList = new ArrayList<>(BASE_EXCLUDE); + excludeList.addAll(permitAllUrl.getUrls()); + registry.addInterceptor(licenseInterceptor) + .addPathPatterns("/**") + .excludePathPatterns(excludeList); + } + } +} diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/domain/.WeDrive b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/domain/.WeDrive new file mode 100644 index 0000000..be19c04 --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/domain/.WeDrive @@ -0,0 +1 @@ +C:\Users\李涛\Documents\WXWork\1688851319997782\WeDrive\福莱瑞达\软件产品中心\软件产品中心共享资料\集成授权码功能\vue版本集成\授权码\ruoyi-license\src\main\java\com\ruoyi\license\domain \ No newline at end of file diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/domain/SysLicense.java b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/domain/SysLicense.java new file mode 100644 index 0000000..90dfc8d --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/domain/SysLicense.java @@ -0,0 +1,105 @@ +package com.ruoyi.license.domain; + +import com.ruoyi.common.core.domain.BaseEntity; +import java.util.Date; + +/** + * 系统授权码对象 sys_license + * + * @author ruoyi + */ +public class SysLicense extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 授权ID */ + private Long licenseId; + + /** 授权码 */ + private String licenseCode; + + /** 授权开始时间 */ + private Date startTime; + + /** 授权结束时间 */ + private Date expireTime; + + /** 授权状态(0未激活 1已激活 2已过期) */ + private String status; + + /** 激活时间 */ + private Date activeTime; + + /** 激活人 */ + private String activeBy; + + public Long getLicenseId() + { + return licenseId; + } + + public void setLicenseId(Long licenseId) + { + this.licenseId = licenseId; + } + + public String getLicenseCode() + { + return licenseCode; + } + + public void setLicenseCode(String licenseCode) + { + this.licenseCode = licenseCode; + } + + public Date getStartTime() + { + return startTime; + } + + public void setStartTime(Date startTime) + { + this.startTime = startTime; + } + + public Date getExpireTime() + { + return expireTime; + } + + public void setExpireTime(Date expireTime) + { + this.expireTime = expireTime; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public Date getActiveTime() + { + return activeTime; + } + + public void setActiveTime(Date activeTime) + { + this.activeTime = activeTime; + } + + public String getActiveBy() + { + return activeBy; + } + + public void setActiveBy(String activeBy) + { + this.activeBy = activeBy; + } +} diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/interceptor/.WeDrive b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/interceptor/.WeDrive new file mode 100644 index 0000000..67e9730 --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/interceptor/.WeDrive @@ -0,0 +1 @@ +C:\Users\李涛\Documents\WXWork\1688851319997782\WeDrive\福莱瑞达\软件产品中心\软件产品中心共享资料\集成授权码功能\vue版本集成\授权码\ruoyi-license\src\main\java\com\ruoyi\license\interceptor \ No newline at end of file diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/interceptor/LicenseInterceptor.java b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/interceptor/LicenseInterceptor.java new file mode 100644 index 0000000..a2cbc64 --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/interceptor/LicenseInterceptor.java @@ -0,0 +1,46 @@ +package com.ruoyi.license.interceptor; + +import java.io.PrintWriter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import com.ruoyi.license.service.ISysLicenseService; + +/** + * 授权拦截器 + * + * @author ruoyi + */ +@Component +public class LicenseInterceptor implements HandlerInterceptor +{ + @Autowired + private ISysLicenseService licenseService; + + @Value("${license.enabled:false}") + private boolean licenseEnabled; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception + { + if (!licenseEnabled) + { + return true; + } + + if (!licenseService.checkLicenseValid()) + { + response.setStatus(HttpServletResponse.SC_OK); + response.setContentType("application/json;charset=UTF-8"); + PrintWriter writer = response.getWriter(); + writer.write("{\"code\":500,\"msg\":\"\u7cfb\u7edf\u6388\u6743\u5df2\u8fc7\u671f\uff0c\u8bf7\u8054\u7cfb\u7ba1\u7406\u5458\u6fc0\u6d3b\u6388\u6743\u7801\"}"); + writer.flush(); + return false; + } + + return true; + } +} diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/mapper/.WeDrive b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/mapper/.WeDrive new file mode 100644 index 0000000..303125d --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/mapper/.WeDrive @@ -0,0 +1 @@ +C:\Users\李涛\Documents\WXWork\1688851319997782\WeDrive\福莱瑞达\软件产品中心\软件产品中心共享资料\集成授权码功能\vue版本集成\授权码\ruoyi-license\src\main\java\com\ruoyi\license\mapper \ No newline at end of file diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/mapper/SysLicenseMapper.java b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/mapper/SysLicenseMapper.java new file mode 100644 index 0000000..bd29eb6 --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/mapper/SysLicenseMapper.java @@ -0,0 +1,67 @@ +package com.ruoyi.license.mapper; + +import com.ruoyi.license.domain.SysLicense; +import java.util.List; + +/** + * 授权码Mapper接口 + * + * @author ruoyi + */ +public interface SysLicenseMapper +{ + /** + * 查询授权码 + * + * @param licenseId 授权码ID + * @return 授权码 + */ + public SysLicense selectSysLicenseById(Long licenseId); + + /** + * 查询授权码列表 + * + * @param sysLicense 授权码 + * @return 授权码集合 + */ + public List selectSysLicenseList(SysLicense sysLicense); + + /** + * 查询当前有效的授权码 + * + * @return 授权码 + */ + public SysLicense selectActiveLicense(); + + /** + * 新增授权码 + * + * @param sysLicense 授权码 + * @return 结果 + */ + public int insertSysLicense(SysLicense sysLicense); + + /** + * 修改授权码 + * + * @param sysLicense 授权码 + * @return 结果 + */ + public int updateSysLicense(SysLicense sysLicense); + + /** + * 删除授权码 + * + * @param licenseId 授权码ID + * @return 结果 + */ + public int deleteSysLicenseById(Long licenseId); + + /** + * 批量删除授权码 + * + * @param licenseIds 需要删除的数据ID + * @return 结果 + */ + public int deleteSysLicenseByIds(String[] licenseIds); +} diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/service/.WeDrive b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/service/.WeDrive new file mode 100644 index 0000000..8e4560f --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/service/.WeDrive @@ -0,0 +1 @@ +C:\Users\李涛\Documents\WXWork\1688851319997782\WeDrive\福莱瑞达\软件产品中心\软件产品中心共享资料\集成授权码功能\vue版本集成\授权码\ruoyi-license\src\main\java\com\ruoyi\license\service \ No newline at end of file diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/service/ISysLicenseService.java b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/service/ISysLicenseService.java new file mode 100644 index 0000000..1a9a225 --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/service/ISysLicenseService.java @@ -0,0 +1,87 @@ +package com.ruoyi.license.service; + +import com.ruoyi.license.domain.SysLicense; +import java.util.List; + +/** + * 授权码Service接口 + * + * @author ruoyi + */ +public interface ISysLicenseService +{ + /** + * 查询授权码 + * + * @param licenseId 授权码ID + * @return 授权码 + */ + public SysLicense selectSysLicenseById(Long licenseId); + + /** + * 查询授权码列表 + * + * @param sysLicense 授权码 + * @return 授权码集合 + */ + public List selectSysLicenseList(SysLicense sysLicense); + + /** + * 新增授权码 + * + * @param sysLicense 授权码 + * @return 结果 + */ + public int insertSysLicense(SysLicense sysLicense); + + /** + * 修改授权码 + * + * @param sysLicense 授权码 + * @return 结果 + */ + public int updateSysLicense(SysLicense sysLicense); + + /** + * 批量删除授权码 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + public int deleteSysLicenseByIds(String ids); + + /** + * 删除授权码信息 + * + * @param licenseId 授权码ID + * @return 结果 + */ + public int deleteSysLicenseById(Long licenseId); + + /** + * 激活授权码 + * + * @param licenseCode 授权码 + * @return 结果 + */ + public int activeLicense(String licenseCode); + + /** + * 检查授权是否有效 + * + * @return true有效 false无效 + */ + public boolean checkLicenseValid(); + + /** + * 获取当前有效授权信息 + * + * @return 授权信息 + */ + public SysLicense getActiveLicense(); + + /** + * 更新过期授权码状态 + */ + public void updateExpiredLicenses(); +} diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/service/impl/.WeDrive b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/service/impl/.WeDrive new file mode 100644 index 0000000..d81aedd --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/service/impl/.WeDrive @@ -0,0 +1 @@ +C:\Users\李涛\Documents\WXWork\1688851319997782\WeDrive\福莱瑞达\软件产品中心\软件产品中心共享资料\集成授权码功能\vue版本集成\授权码\ruoyi-license\src\main\java\com\ruoyi\license\service\impl \ No newline at end of file diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/service/impl/SysLicenseServiceImpl.java b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/service/impl/SysLicenseServiceImpl.java new file mode 100644 index 0000000..79f070c --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/service/impl/SysLicenseServiceImpl.java @@ -0,0 +1,266 @@ +package com.ruoyi.license.service.impl; + +import java.util.Date; +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.license.domain.SysLicense; +import com.ruoyi.license.mapper.SysLicenseMapper; +import com.ruoyi.license.service.ISysLicenseService; +import com.ruoyi.license.util.LicenseUtils; + +/** + * 授权码Service业务层处理 + * + * @author ruoyi + */ +@Service +public class SysLicenseServiceImpl implements ISysLicenseService +{ + @Autowired + private SysLicenseMapper sysLicenseMapper; + + @Autowired + private com.ruoyi.system.mapper.SysConfigMapper sysConfigMapper; + + @org.springframework.beans.factory.annotation.Value("${license.enabled:false}") + private boolean licenseEnabled; + + /** + * 查询授权码 + * + * @param licenseId 授权码ID + * @return 授权码 + */ + @Override + public SysLicense selectSysLicenseById(Long licenseId) + { + return sysLicenseMapper.selectSysLicenseById(licenseId); + } + + /** + * 查询授权码列表 + * + * @param sysLicense 授权码 + * @return 授权码 + */ + @Override + public List selectSysLicenseList(SysLicense sysLicense) + { + return sysLicenseMapper.selectSysLicenseList(sysLicense); + } + + /** + * 新增授权码 + * + * @param sysLicense 授权码 + * @return 结果 + */ + @Override + public int insertSysLicense(SysLicense sysLicense) + { + sysLicense.setCreateTime(new Date()); + return sysLicenseMapper.insertSysLicense(sysLicense); + } + + /** + * 修改授权码 + * + * @param sysLicense 授权码 + * @return 结果 + */ + @Override + public int updateSysLicense(SysLicense sysLicense) + { + sysLicense.setUpdateTime(new Date()); + return sysLicenseMapper.updateSysLicense(sysLicense); + } + + /** + * 删除授权码对象 + * + * @param ids 需要删除的数据ID + * @return 结果 + */ + @Override + public int deleteSysLicenseByIds(String ids) + { + return sysLicenseMapper.deleteSysLicenseByIds(Convert.toStrArray(ids)); + } + + /** + * 删除授权码信息 + * + * @param licenseId 授权码ID + * @return 结果 + */ + @Override + public int deleteSysLicenseById(Long licenseId) + { + return sysLicenseMapper.deleteSysLicenseById(licenseId); + } + + /** + * 激活授权码 + * + * @param licenseCode 授权码 + * @return 结果 + */ + @Override + public int activeLicense(String licenseCode) + { + if (StringUtils.isEmpty(licenseCode)) + { + return 0; + } + + // 验证授权码格式 + if (!LicenseUtils.validateFormat(licenseCode)) + { + return 0; + } + + try + { + // 从配置表获取项目编号 + String projectNo = sysConfigMapper.selectConfigByKey("fortucky.project.no"); + if (StringUtils.isEmpty(projectNo)) + { + return 0; + } + + // 解析授权码 + long expireTime = LicenseUtils.parseLicense(licenseCode, projectNo); + if (expireTime == 0) + { + return 0; + } + + Date now = new Date(); + Date startTime = now; + Date expireDate = new Date(expireTime); + + // 验证是否已过期 + if (expireDate.before(now)) + { + return 0; + } + + // 创建授权记录 + SysLicense license = new SysLicense(); + license.setLicenseCode(licenseCode); + license.setStartTime(startTime); + license.setExpireTime(expireDate); + license.setStatus("1"); + license.setActiveTime(now); + license.setCreateTime(now); + + return sysLicenseMapper.insertSysLicense(license); + } + catch (Exception e) + { + return 0; + } + } + + /** + * 检查授权是否有效 + * + * @return true有效 false无效 + */ + @Override + public boolean checkLicenseValid() + { + // 如果授权码功能未启用,直接返回true + if (!licenseEnabled) + { + return true; + } + + SysLicense license = sysLicenseMapper.selectActiveLicense(); + if (license == null) + { + System.out.println("[授权检查] 没有找到激活的授权码"); + return false; + } + + // 从配置表获取项目编号 + String projectNo = sysConfigMapper.selectConfigByKey("fortucky.project.no"); + if (StringUtils.isEmpty(projectNo)) + { + System.out.println("[授权检查] 项目编号未配置"); + return false; + } + + System.out.println("[授权检查] 授权码: " + license.getLicenseCode()); + System.out.println("[授权检查] 项目编号: " + projectNo); + + // 从授权码解析过期时间 + long expireTime = LicenseUtils.parseLicense(license.getLicenseCode(), projectNo); + if (expireTime == 0) + { + System.out.println("[授权检查] 授权码解析失败"); + return false; + } + + Date now = new Date(); + System.out.println("[授权检查] 当前时间: " + now.getTime()); + System.out.println("[授权检查] 过期时间: " + expireTime); + + if (expireTime < now.getTime()) + { + System.out.println("[授权检查] 授权已过期"); + // 更新为过期状态 + license.setStatus("2"); + sysLicenseMapper.updateSysLicense(license); + return false; + } + + + return true; + } + + /** + * 获取当前有效授权信息 + * + * @return 授权信息 + */ + @Override + public SysLicense getActiveLicense() + { + return sysLicenseMapper.selectActiveLicense(); + } + + /** + * 更新过期授权码状态 + */ + @Override + public void updateExpiredLicenses() + { + SysLicense query = new SysLicense(); + query.setStatus("1"); + List licenses = sysLicenseMapper.selectSysLicenseList(query); + + // 从配置表获取项目编号 + String projectNo = sysConfigMapper.selectConfigByKey("fortucky.project.no"); + if (StringUtils.isEmpty(projectNo)) + { + return; + } + + Date now = new Date(); + for (SysLicense license : licenses) + { + // 从授权码解析过期时间 + long expireTime = LicenseUtils.parseLicense(license.getLicenseCode(), projectNo); + if (expireTime > 0 && expireTime < now.getTime()) + { + license.setStatus("2"); + license.setUpdateTime(now); + sysLicenseMapper.updateSysLicense(license); + } + } + } +} diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/task/.WeDrive b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/task/.WeDrive new file mode 100644 index 0000000..27b60e6 --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/task/.WeDrive @@ -0,0 +1 @@ +C:\Users\李涛\Documents\WXWork\1688851319997782\WeDrive\福莱瑞达\软件产品中心\软件产品中心共享资料\集成授权码功能\vue版本集成\授权码\ruoyi-license\src\main\java\com\ruoyi\license\task \ No newline at end of file diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/task/LicenseCheckTask.java b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/task/LicenseCheckTask.java new file mode 100644 index 0000000..9963c61 --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/task/LicenseCheckTask.java @@ -0,0 +1,47 @@ +package com.ruoyi.license.task; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.license.service.ISysLicenseService; + +/** + * 授权检查定时任务 + * + * @author ruoyi + */ +@Component +public class LicenseCheckTask +{ + @Autowired + private ISysLicenseService licenseService; + + @Autowired + private RedisCache redisCache; + + @Value("${license.enabled:false}") + private boolean licenseEnabled; + + /** + * 每5分钟检查一次授权状态 + */ + @Scheduled(cron = "0 */5 * * * ?") + public void checkLicense() + { + if (!licenseEnabled) + { + return; + } + + if (!licenseService.checkLicenseValid()) + { + // 授权无效,删除 Redis 中所有登录 token,强制踢出所有在线用户 + redisCache.deleteObject(redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*")); + } + + licenseService.updateExpiredLicenses(); + } +} diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/util/.WeDrive b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/util/.WeDrive new file mode 100644 index 0000000..2fb358f --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/util/.WeDrive @@ -0,0 +1 @@ +C:\Users\李涛\Documents\WXWork\1688851319997782\WeDrive\福莱瑞达\软件产品中心\软件产品中心共享资料\集成授权码功能\vue版本集成\授权码\ruoyi-license\src\main\java\com\ruoyi\license\util \ No newline at end of file diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/util/LicenseGenerator.java b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/util/LicenseGenerator.java new file mode 100644 index 0000000..16ce407 --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/util/LicenseGenerator.java @@ -0,0 +1,127 @@ +package com.ruoyi.license.util; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Scanner; + +/** + * 授权码生成工具(独立运行) + * + * @author ruoyi + */ +public class LicenseGenerator +{ + public static void main(String[] args) + { + Scanner scanner = new Scanner(System.in); + + System.out.println("========================================"); + System.out.println(" RuoYi 授权码生成工具"); + System.out.println("========================================"); + System.out.println(); + + try + { + // 选择授权类型 + System.out.println("请选择授权类型:"); + System.out.println("1. 5分钟测试"); + System.out.println("2. 1个月授权"); + System.out.println("3. 3个月授权"); + System.out.println("4. 1年授权"); + System.out.println("5. 5年授权"); + System.out.println("6. 长期授权"); + System.out.print("请输入选项(1-6): "); + String typeChoice = scanner.nextLine().trim(); + + String type; + String typeDesc; + long expireTime; + + switch (typeChoice) + { + case "1": + type = LicenseUtils.TYPE_TEST; + typeDesc = "5分钟测试"; + expireTime = System.currentTimeMillis() + 5 * 60 * 1000L; + break; + case "2": + type = LicenseUtils.TYPE_MONTH; + typeDesc = "1个月授权"; + expireTime = System.currentTimeMillis() + 30L * 24 * 60 * 60 * 1000; + break; + case "3": + type = LicenseUtils.TYPE_THREE; + typeDesc = "3个月授权"; + expireTime = System.currentTimeMillis() + 90L * 24 * 60 * 60 * 1000; + break; + case "4": + type = LicenseUtils.TYPE_YEAR; + typeDesc = "1年授权"; + expireTime = System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000; + break; + case "5": + type = LicenseUtils.TYPE_FIVE; + typeDesc = "5年授权"; + expireTime = System.currentTimeMillis() + 5 * 365L * 24 * 60 * 60 * 1000; + break; + case "6": + type = LicenseUtils.TYPE_FOREVER; + typeDesc = "长期授权"; + expireTime = System.currentTimeMillis() + 100 * 365L * 24 * 60 * 60 * 1000; + break; + default: + System.out.println("错误:无效的选项"); + return; + } + + // 输入项目编号 + System.out.print("请输入项目编号: "); + String projectNo = scanner.nextLine().trim(); + + if (projectNo.isEmpty()) + { + System.out.println("错误:项目编号不能为空"); + return; + } + + // 生成授权码 + String licenseCode = LicenseUtils.generateLicense(type, projectNo); + + if (licenseCode == null) + { + System.out.println("错误:授权码生成失败"); + return; + } + + // 格式化日期 + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date now = new Date(); + Date expire = new Date(expireTime); + + System.out.println(); + System.out.println("========================================"); + System.out.println("授权码生成成功!"); + System.out.println("========================================"); + System.out.println("授权类型: " + typeDesc); + System.out.println("项目编号: " + projectNo); + System.out.println("当前时间: " + sdf.format(now)); + System.out.println("过期时间: " + sdf.format(expire)); + System.out.println("----------------------------------------"); + System.out.println("授权码:"); + System.out.println(licenseCode); + System.out.println("========================================"); + System.out.println(); + System.out.println("请妥善保管授权码,在系统中激活后即可使用。"); + System.out.println("注意:系统配置中的项目编号必须与此处一致才能激活。"); + } + catch (Exception e) + { + System.out.println("错误:" + e.getMessage()); + e.printStackTrace(); + } + finally + { + scanner.close(); + } + } +} diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/util/LicenseTest.java b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/util/LicenseTest.java new file mode 100644 index 0000000..0b69a1c --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/util/LicenseTest.java @@ -0,0 +1,89 @@ +package com.ruoyi.license.util; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 授权码测试工具 + * + * @author ruoyi + */ +public class LicenseTest +{ + public static void main(String[] args) + { + System.out.println("========================================"); + System.out.println(" 授权码功能测试"); + System.out.println("========================================"); + System.out.println(); + + String projectNo = "TEST001"; + + // 测试1:生成各类型授权码 + System.out.println("【测试1】生成各类型授权码"); + String testCode = LicenseUtils.generateLicense(LicenseUtils.TYPE_TEST, projectNo); + String yearCode = LicenseUtils.generateLicense(LicenseUtils.TYPE_YEAR, projectNo); + String fiveCode = LicenseUtils.generateLicense(LicenseUtils.TYPE_FIVE, projectNo); + String foreverCode = LicenseUtils.generateLicense(LicenseUtils.TYPE_FOREVER, projectNo); + + System.out.println("5分钟测试: " + testCode); + System.out.println("1年授权: " + yearCode); + System.out.println("5年授权: " + fiveCode); + System.out.println("长期授权: " + foreverCode); + System.out.println("结果: ✓ 通过"); + System.out.println(); + + // 测试2:验证授权码格式 + System.out.println("【测试2】验证授权码格式"); + boolean isValid = LicenseUtils.validateFormat(yearCode); + System.out.println("格式验证: " + (isValid ? "✓ 通过" : "✗ 失败")); + System.out.println(); + + // 测试3:解析授权码 + System.out.println("【测试3】解析授权码"); + long expireTime = LicenseUtils.parseLicense(yearCode, projectNo); + if (expireTime > 0) + { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date expire = new Date(expireTime); + System.out.println("过期时间: " + sdf.format(expire)); + System.out.println("结果: ✓ 通过"); + } + else + { + System.out.println("结果: ✗ 失败"); + } + System.out.println(); + + // 测试4:项目编号验证 + System.out.println("【测试4】项目编号验证"); + long validResult = LicenseUtils.parseLicense(yearCode, projectNo); + long invalidResult = LicenseUtils.parseLicense(yearCode, "WRONG001"); + System.out.println("正确项目编号: " + (validResult > 0 ? "✓ 通过" : "✗ 失败")); + System.out.println("错误项目编号: " + (invalidResult == 0 ? "✓ 通过(正确拒绝)" : "✗ 失败")); + System.out.println(); + + // 测试5:授权码格式展示 + System.out.println("【测试5】授权码格式展示"); + System.out.println("授权码: " + yearCode); + String[] parts = yearCode.split("_"); + if (parts.length == 5) + { + System.out.println("前缀: " + parts[0]); + System.out.println("类型: " + parts[1] + " (" + LicenseUtils.getTypeDesc(parts[1]) + ")"); + System.out.println("项目编号: " + parts[2]); + System.out.println("加密时间: " + parts[3]); + System.out.println("校验码: " + parts[4]); + System.out.println("结果: ✓ 通过"); + } + else + { + System.out.println("结果: ✗ 失败"); + } + System.out.println(); + + System.out.println("========================================"); + System.out.println("测试完成!"); + System.out.println("========================================"); + } +} diff --git a/dosc/ruoyi-license/src/main/java/com/ruoyi/license/util/LicenseUtils.java b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/util/LicenseUtils.java new file mode 100644 index 0000000..ef456ae --- /dev/null +++ b/dosc/ruoyi-license/src/main/java/com/ruoyi/license/util/LicenseUtils.java @@ -0,0 +1,275 @@ +package com.ruoyi.license.util; + +import java.util.Base64; +import java.util.Date; +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + +/** + * 授权码工具类 + * 格式: FORTUCKY_授权类型_项目编号_加密时间_校验码 + * + * @author ruoyi + */ +public class LicenseUtils +{ + // 密钥(16位) + private static final String SECRET_KEY = "RuoYiLicense2024"; + + // 授权类型 + public static final String TYPE_TEST = "TEST"; // 5分钟测试 + public static final String TYPE_MONTH = "MONTH"; // 1个月 + public static final String TYPE_THREE = "THREE"; // 3个月 + public static final String TYPE_YEAR = "YEAR"; // 1年 + public static final String TYPE_FIVE = "FIVE"; // 5年 + public static final String TYPE_FOREVER = "FOREVER"; // 长期 + + /** + * 生成授权码 + * + * @param type 授权类型 + * @param projectNo 项目编号 + * @return 授权码 + */ + public static String generateLicense(String type, String projectNo) + { + try + { + long expireTime = calculateExpireTime(type); + if (expireTime == 0) + { + return null; + } + + // 加密过期时间 + String encryptedTime = encrypt(String.valueOf(expireTime)); + if (encryptedTime == null) + { + return null; + } + + // 生成校验码(取加密时间的前8位MD5) + String checkCode = generateCheckCode(type, projectNo, encryptedTime); + + // 拼接授权码: FORTUCKY_类型_项目编号_加密时间_校验码 + return "FORTUCKY_" + type + "_" + projectNo + "_" + encryptedTime + "_" + checkCode; + } + catch (Exception e) + { + return null; + } + } + + /** + * 验证授权码格式 + * + * @param licenseCode 授权码 + * @return true有效 false无效 + */ + public static boolean validateFormat(String licenseCode) + { + if (licenseCode == null || licenseCode.trim().isEmpty()) + { + return false; + } + + String[] parts = licenseCode.split("_"); + if (parts.length != 5) + { + return false; + } + + if (!"FORTUCKY".equals(parts[0])) + { + return false; + } + + // 验证授权类型 + String type = parts[1]; + if (!TYPE_TEST.equals(type) && !TYPE_MONTH.equals(type) && !TYPE_THREE.equals(type) && + !TYPE_YEAR.equals(type) && !TYPE_FIVE.equals(type) && !TYPE_FOREVER.equals(type)) + { + return false; + } + + return true; + } + + /** + * 解析授权码 + * + * @param licenseCode 授权码 + * @param projectNo 系统项目编号 + * @return 过期时间戳,0表示解析失败 + */ + public static long parseLicense(String licenseCode, String projectNo) + { + try + { + if (!validateFormat(licenseCode)) + { + return 0; + } + + String[] parts = licenseCode.split("_"); + String type = parts[1]; + String codeProjectNo = parts[2]; + String encryptedTime = parts[3]; + String checkCode = parts[4]; + + // 验证项目编号 + if (!codeProjectNo.equals(projectNo)) + { + return 0; + } + + // 验证校验码 + String expectedCheckCode = generateCheckCode(type, codeProjectNo, encryptedTime); + if (!checkCode.equals(expectedCheckCode)) + { + return 0; + } + + // 解密时间 + String decrypted = decrypt(encryptedTime); + if (decrypted == null) + { + return 0; + } + + return Long.parseLong(decrypted); + } + catch (Exception e) + { + return 0; + } + } + + /** + * 获取授权类型描述 + * + * @param type 授权类型 + * @return 描述 + */ + public static String getTypeDesc(String type) + { + switch (type) + { + case TYPE_TEST: return "5分钟测试"; + case TYPE_MONTH: return "1个月授权"; + case TYPE_THREE: return "3个月授权"; + case TYPE_YEAR: return "1年授权"; + case TYPE_FIVE: return "5年授权"; + case TYPE_FOREVER: return "长期授权"; + default: return "未知"; + } + } + + /** + * 计算过期时间 + * + * @param type 授权类型 + * @return 过期时间戳 + */ + private static long calculateExpireTime(String type) + { + long now = System.currentTimeMillis(); + + switch (type) + { + case TYPE_TEST: + return now + 5 * 60 * 1000L; // 5分钟 + case TYPE_MONTH: + return now + 30L * 24 * 60 * 60 * 1000; // 1个月 + case TYPE_THREE: + return now + 90L * 24 * 60 * 60 * 1000; // 3个月 + case TYPE_YEAR: + return now + 365L * 24 * 60 * 60 * 1000; // 1年 + case TYPE_FIVE: + return now + 5 * 365L * 24 * 60 * 60 * 1000; // 5年 + case TYPE_FOREVER: + return now + 100 * 365L * 24 * 60 * 60 * 1000; // 100年(视为长期) + default: + return 0; + } + } + + /** + * 生成校验码 + * + * @param type 授权类型 + * @param projectNo 项目编号 + * @param encryptedTime 加密时间 + * @return 校验码 + */ + private static String generateCheckCode(String type, String projectNo, String encryptedTime) + { + try + { + String data = type + projectNo + encryptedTime; + java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5"); + byte[] hash = md.digest(data.getBytes("UTF-8")); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < Math.min(4, hash.length); i++) + { + sb.append(String.format("%02x", hash[i])); + } + return sb.toString().toUpperCase(); + } + catch (Exception e) + { + return "00000000"; + } + } + + /** + * 加密 + * + * @param data 原始数据 + * @return 加密后的数据 + */ + private static String encrypt(String data) + { + try + { + SecretKeySpec key = new SecretKeySpec(SECRET_KEY.getBytes("UTF-8"), "AES"); + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, key); + byte[] encrypted = cipher.doFinal(data.getBytes("UTF-8")); + return Base64.getEncoder().encodeToString(encrypted).replace("+", "-").replace("/", ".").replace("=", ""); + } + catch (Exception e) + { + return null; + } + } + + /** + * 解密 + * + * @param encryptedData 加密数据 + * @return 解密后的数据 + */ + private static String decrypt(String encryptedData) + { + try + { + String base64Data = encryptedData.replace("-", "+").replace(".", "/"); + int padding = (4 - base64Data.length() % 4) % 4; + for (int i = 0; i < padding; i++) + { + base64Data += "="; + } + + SecretKeySpec key = new SecretKeySpec(SECRET_KEY.getBytes("UTF-8"), "AES"); + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); + cipher.init(Cipher.DECRYPT_MODE, key); + byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(base64Data)); + return new String(decrypted, "UTF-8"); + } + catch (Exception e) + { + return null; + } + } +} diff --git a/dosc/ruoyi-license/src/main/resources/mapper/license/.WeDrive b/dosc/ruoyi-license/src/main/resources/mapper/license/.WeDrive new file mode 100644 index 0000000..f82e862 --- /dev/null +++ b/dosc/ruoyi-license/src/main/resources/mapper/license/.WeDrive @@ -0,0 +1 @@ +C:\Users\李涛\Documents\WXWork\1688851319997782\WeDrive\福莱瑞达\软件产品中心\软件产品中心共享资料\集成授权码功能\vue版本集成\授权码\ruoyi-license\src\main\resources\mapper\license \ No newline at end of file diff --git a/dosc/ruoyi-license/src/main/resources/mapper/license/SysLicenseMapper.xml b/dosc/ruoyi-license/src/main/resources/mapper/license/SysLicenseMapper.xml new file mode 100644 index 0000000..e6603f0 --- /dev/null +++ b/dosc/ruoyi-license/src/main/resources/mapper/license/SysLicenseMapper.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + select license_id, license_code, start_time, expire_time, status, active_time, active_by, create_by, create_time, update_by, update_time, remark from sys_license + + + + + + + + + + insert into sys_license + + license_code, + start_time, + expire_time, + status, + active_time, + active_by, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{licenseCode}, + #{startTime}, + #{expireTime}, + #{status}, + #{activeTime}, + #{activeBy}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + update sys_license + + license_code = #{licenseCode}, + start_time = #{startTime}, + expire_time = #{expireTime}, + status = #{status}, + active_time = #{activeTime}, + active_by = #{activeBy}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where license_id = #{licenseId} + + + + delete from sys_license where license_id = #{licenseId} + + + + delete from sys_license where license_id in + + #{licenseId} + + + + diff --git a/dosc/vue授权码.md b/dosc/vue授权码.md new file mode 100644 index 0000000..d6c8609 --- /dev/null +++ b/dosc/vue授权码.md @@ -0,0 +1,270 @@ +# 授权码模块集成改动说明 + +> 本文档记录引入 `ruoyi-license` 授权码模块时,对原有项目文件的所有改动(不含 `ruoyi-license` 模块本身及 `SysLicenseController`)。 + +--- + +## 1. 根模块 `pom.xml` + +**文件路径:** `wms/pom.xml` + +**改动内容:** + +1. `` 中注册 `ruoyi-license` 子模块: + +```xml + + ruoyi-admin + ruoyi-framework + ruoyi-system + ruoyi-quartz + ruoyi-generator + ruoyi-common + ruoyi-license + +``` + +2. `` 中声明 `ruoyi-license` 依赖版本: + +```xml + + + com.ruoyi + ruoyi-license + ${ruoyi.version} + +``` + +--- + +## 2. `ruoyi-admin/pom.xml` + +**文件路径:** `wms/ruoyi-admin/pom.xml` + +**改动内容:** + +引入 `ruoyi-license` 依赖,使授权拦截器和配置能被 Spring Boot 扫描加载: + +```xml + + + com.ruoyi + ruoyi-license + +``` + +--- + +## 3. `SecurityConfig.java` + +**文件路径:** `wms/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java` + +**改动内容:** + +在 Spring Security 匿名白名单中加入 `/system/license/active`,允许未登录用户调用激活授权码接口: + +```java +// 改动前 +requests.antMatchers("/login", "/register", "/captchaImage").permitAll() + +// 改动后 +requests.antMatchers("/login", "/register", "/captchaImage", "/system/license/active").permitAll() +``` + +--- + +## 4. 前端 `api/license.js`(新建) + +**文件路径:** `wms/ui/src/api/license.js` + +**改动内容:** + +新建文件,封装授权码相关接口: + +```js +import request from '@/utils/request' + +// 激活授权码(无需登录) +export function activeLicense(licenseCode) { + return request({ + url: '/system/license/active', + method: 'post', + params: { licenseCode } + }) +} + +// 查询当前授权信息(需登录) +export function getLicenseInfo() { + return request({ + url: '/system/license/info', + method: 'get' + }) +} +``` + +--- + +## 5. 登录页 `login.vue` + +**文件路径:** `wms/ui/src/views/login.vue` + +**改动内容:** + +### 5.1 模板部分 + +在登录按钮下方新增"激活授权码"按钮,以及激活弹窗: + +```html + + + 激活授权码 + + + + + + + 取 消 + 激 活 + + +``` + +### 5.2 Script 部分 + +新增 import、data 字段和方法: + +```js +// 新增 import +import { activeLicense } from "@/api/license" + +// 新增 data 字段 +licenseDialogVisible: false, +licenseCode: '', +licenseLoading: false + +// 新增方法 +openLicenseDialog() { + this.licenseCode = '' + this.licenseDialogVisible = true +}, +handleActiveLicense() { + if (!this.licenseCode.trim()) { + this.$message.warning('请输入授权码') + return + } + this.licenseLoading = true + activeLicense(this.licenseCode.trim()).then(res => { + if (res.code === 200) { + this.$message.success(res.msg || '授权码激活成功') + this.licenseDialogVisible = false + } else { + this.$message.error(res.msg || '授权码激活失败') + } + }).catch(() => { + this.$message.error('授权码激活失败') + }).finally(() => { + this.licenseLoading = false + }) +} +``` + +--- + +## 6. 顶部导航栏 `Navbar.vue` + +**文件路径:** `wms/ui/src/layout/components/Navbar.vue` + +**改动内容:** + +### 6.1 模板部分 + +在 navbar 中间插入授权到期警告条(剩余不足 30 天时显示): + +```html +
+ + 系统授权将于 {{ licenseExpireText }} 后过期,请及时联系管理员续期 +
+``` + +### 6.2 Script 部分 + +```js +// 新增 import +import { getLicenseInfo } from '@/api/license' + +// 新增 data 字段 +licenseWarning: false, +licenseExpireText: '', +licenseTimer: null + +// 新增生命周期钩子 +mounted() { + this.checkLicenseExpire() + this.licenseTimer = setInterval(() => this.checkLicenseExpire(), 60 * 1000) +}, +beforeDestroy() { + if (this.licenseTimer) clearInterval(this.licenseTimer) +}, + +// 新增方法 +checkLicenseExpire() { + getLicenseInfo().then(res => { + if (res.code === 200 && res.data && res.data.expireTime) { + const expireTime = new Date(res.data.expireTime).getTime() + const now = Date.now() + const diffMs = expireTime - now + const diffDays = Math.ceil(diffMs / (1000 * 60 * 60 * 24)) + if (diffMs > 0 && diffDays <= 30) { + this.licenseWarning = true + if (diffMs < 1000 * 60 * 60 * 24) { + const hours = Math.floor(diffMs / (1000 * 60 * 60)) + const minutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60)) + this.licenseExpireText = hours > 0 ? `${hours} 小时 ${minutes} 分钟` : `${minutes} 分钟` + } else if (diffDays < 7) { + this.licenseExpireText = diffDays + ' 天' + } else { + this.licenseExpireText = Math.ceil(diffDays / 7) + ' 周' + } + } + } + }).catch(() => {}) +} +``` + +### 6.3 样式部分 + +```scss +.license-warning { + position: absolute; + left: 50%; + transform: translateX(-50%); + top: 0; + height: 50px; + line-height: 50px; + font-size: 13px; + color: #e6a23c; + font-weight: 500; + pointer-events: none; + i { margin-right: 4px; } +} +``` + +--- + +## 改动文件汇总 + +| 文件 | 类型 | 说明 | +|---|---|---| +| `wms/pom.xml` | 修改 | 注册模块 + 声明依赖版本 | +| `wms/ruoyi-admin/pom.xml` | 修改 | 引入 ruoyi-license 依赖 | +| `ruoyi-framework/.../SecurityConfig.java` | 修改 | 白名单加入激活授权码接口 | +| `ui/src/api/license.js` | 新建 | 封装激活和查询授权信息接口 | +| `ui/src/views/login.vue` | 修改 | 新增激活授权码按钮和弹窗 | +| `ui/src/layout/components/Navbar.vue` | 修改 | 新增授权到期倒计时警告条 | diff --git a/dosc/授权码vue版本配置手册.docx b/dosc/授权码vue版本配置手册.docx new file mode 100644 index 0000000..e6458c6 Binary files /dev/null and b/dosc/授权码vue版本配置手册.docx differ diff --git a/fortucky-algorithm/pom.xml b/fortucky-algorithm/pom.xml new file mode 100644 index 0000000..ff098ee --- /dev/null +++ b/fortucky-algorithm/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + + com.ruoyi + ruoyi + 3.9.0 + + + fortucky-algorithm + jar + FT546 密集库 Java 调度算法与 WMS 接入门面 + + + + org.springframework + spring-jdbc + + + org.springframework.boot + spring-boot-autoconfigure + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + com.h2database + h2 + test + + + com.fasterxml.jackson.core + jackson-databind + test + + + diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/LaneAnalyzer.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/LaneAnalyzer.java new file mode 100644 index 0000000..6aa4ddc --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/LaneAnalyzer.java @@ -0,0 +1,79 @@ +package com.ruoyi.algorithm; + +import com.ruoyi.algorithm.model.LaneState; +import com.ruoyi.algorithm.model.SpaceState; +import com.ruoyi.algorithm.model.SpaceStatus; +import com.ruoyi.algorithm.policy.SchedulingPolicy; + +import java.util.Comparator; +import java.util.List; +import java.util.Optional; + +public final class LaneAnalyzer { + + public LaneState analyze(List laneSpaces, SchedulingPolicy policy) { + List spaces = laneSpaces.stream() + .sorted(Comparator.comparingInt(SpaceState::depthOrder)) + .toList(); + + boolean emptySeen = false; + boolean physicallyContinuous = true; + boolean invalidInventoryState = false; + int segmentCount = 0; + String currentSegmentKey = null; + String residentProject = null; + String guestProject = null; + + for (SpaceState space : spaces) { + boolean occupied = space.occupied(); + if (!occupied) { + emptySeen = true; + continue; + } + + if (emptySeen) { + physicallyContinuous = false; + } + if (space.inventoryProjectConflict() + || (space.status() == SpaceStatus.EMPTY && space.hasTray())) { + invalidInventoryState = true; + } + + String segmentKey = space.projectNo() == null ? "__UNKNOWN__" : space.projectNo(); + if (!segmentKey.equals(currentSegmentKey)) { + currentSegmentKey = segmentKey; + segmentCount++; + if (segmentCount == 1) { + residentProject = space.projectNo(); + } else if (segmentCount == 2) { + guestProject = space.projectNo(); + } + } + } + + boolean corrupt = invalidInventoryState || !physicallyContinuous || segmentCount > 2; + Optional nextSlot = corrupt + ? Optional.empty() + : spaces.stream().filter(SpaceState::availableEmpty).findFirst(); + int outermostOccupiedDepth = spaces.stream() + .filter(SpaceState::occupied) + .mapToInt(SpaceState::depthOrder) + .max() + .orElse(0); + Optional outerSlot = spaces.stream() + .filter(SpaceState::availableEmpty) + .filter(space -> space.depthOrder() > outermostOccupiedDepth) + .findFirst(); + + return new LaneState( + spaces, + physicallyContinuous, + corrupt, + segmentCount, + Optional.ofNullable(residentProject), + Optional.ofNullable(guestProject), + nextSlot, + outerSlot + ); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/BatchLaneMode.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/BatchLaneMode.java new file mode 100644 index 0000000..2364e23 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/BatchLaneMode.java @@ -0,0 +1,6 @@ +package com.ruoyi.algorithm.inbound; + +public enum BatchLaneMode { + OPEN, + SEALED +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundAssignment.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundAssignment.java new file mode 100644 index 0000000..e3c810a --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundAssignment.java @@ -0,0 +1,20 @@ +package com.ruoyi.algorithm.inbound; + +public record InboundAssignment( + String requestId, + String spaceId, + String laneCode, + int laneCapacity, + int depthOrder, + InboundLadderRung ladderRung, + InboundBorrowType borrowType, + String mixedIntoResidentProject, + double capacityScore, + double efficiencyScore, + double totalScore, + double fillRatePercent, + boolean batchLaneApplied, + boolean openedNewLane, + String reason +) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundBorrowType.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundBorrowType.java new file mode 100644 index 0000000..4cc1233 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundBorrowType.java @@ -0,0 +1,8 @@ +package com.ruoyi.algorithm.inbound; + +public enum InboundBorrowType { + NONE, + CACHE_BORROWED, + RESERVE_BORROWED, + MIXED_IN +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundContext.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundContext.java new file mode 100644 index 0000000..6e042e6 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundContext.java @@ -0,0 +1,19 @@ +package com.ruoyi.algorithm.inbound; + +import com.ruoyi.algorithm.model.SpaceState; + +import java.util.List; + +public record InboundContext( + List spaces, + InboundPolicy policy, + List pendingOutbounds, + int occupiedCount +) { + public InboundContext { + spaces = spaces == null ? List.of() : List.copyOf(spaces); + policy = policy == null ? InboundPolicy.defaults() : policy; + pendingOutbounds = pendingOutbounds == null ? List.of() : List.copyOf(pendingOutbounds); + if (occupiedCount < 0) throw new IllegalArgumentException("occupiedCount cannot be negative"); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundLadderRung.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundLadderRung.java new file mode 100644 index 0000000..4834279 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundLadderRung.java @@ -0,0 +1,12 @@ +package com.ruoyi.algorithm.inbound; + +public enum InboundLadderRung { + CONTINUE, + OPEN_GRADED, + OPEN_ADJACENT, + MIXED_GUEST, + POOL_BORROW, + COMMON_SINGLE, + COMMON_LANE_CONTINUE, + COMMON_LANE_OPEN +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundPlan.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundPlan.java new file mode 100644 index 0000000..3df424c --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundPlan.java @@ -0,0 +1,21 @@ +package com.ruoyi.algorithm.inbound; + +import java.util.Optional; + +public record InboundPlan(Optional assignment, Optional rejection) { + public InboundPlan { + assignment = assignment == null ? Optional.empty() : assignment; + rejection = rejection == null ? Optional.empty() : rejection; + if (assignment.isPresent() == rejection.isPresent()) { + throw new IllegalArgumentException("plan must contain exactly one assignment or rejection"); + } + } + + public static InboundPlan assigned(InboundAssignment assignment) { + return new InboundPlan(Optional.of(assignment), Optional.empty()); + } + + public static InboundPlan rejected(InboundRejection rejection) { + return new InboundPlan(Optional.empty(), Optional.of(rejection)); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundPlanner.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundPlanner.java new file mode 100644 index 0000000..51edcb4 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundPlanner.java @@ -0,0 +1,674 @@ +package com.ruoyi.algorithm.inbound; + +import com.ruoyi.algorithm.model.SpaceRole; +import com.ruoyi.algorithm.model.SpaceState; +import com.ruoyi.algorithm.model.SpaceStatus; +import com.ruoyi.algorithm.policy.SchedulingPolicy; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +public final class InboundPlanner { + private static final Map> ADJACENT_DEPTH_ORDER = Map.of( + 2, List.of(3, 5), + 3, List.of(5, 2), + 5, List.of(3, 2) + ); + + public InboundPlan plan(InboundRequest request, InboundContext context) { + Objects.requireNonNull(request, "request"); + Objects.requireNonNull(context, "context"); + validateManualReservations(context); + List lanes = buildLanes(context); + + Optional selected = context.policy().isCommon(request.projectNo()) + ? chooseCommon(request, context, lanes) + : chooseProject(request, context, lanes); + if (selected.isPresent()) { + return InboundPlan.assigned(toAssignment(request, selected.orElseThrow())); + } + + List trace = traceFor(request, context, lanes); + boolean sealedProjectRequest = request.batchLaneMode() == BatchLaneMode.SEALED + && !context.policy().isCommon(request.projectNo()); + InboundRejectionCode code = sealedProjectRequest + ? InboundRejectionCode.NO_BATCH_COMPATIBLE_LANE + : InboundRejectionCode.NO_FEASIBLE_LOCATION; + String reason = sealedProjectRequest + ? "No lane can continue the same project, product and lot, and no completely empty lane remains." + : "Inbound admission ladder exhausted every legal location; no feasible location remains."; + return InboundPlan.rejected(new InboundRejection( + code, reason, request.projectNo(), request.productId(), request.lotNo(), trace)); + } + + public PagedSession startPaged(InboundRequest request, InboundPolicy policy, + List pendingOutbounds, int occupiedCount) { + return new PagedSession(request, policy, pendingOutbounds, occupiedCount); + } + + public final class PagedSession { + private final InboundRequest request; + private final InboundPolicy policy; + private final List pendingOutbounds; + private final int occupiedCount; + private final Map retained = new LinkedHashMap<>(); + private final java.util.Set missingManualLanes; + private long freeSinglePool; + + private PagedSession(InboundRequest request, InboundPolicy policy, + List pendingOutbounds, int occupiedCount) { + this.request = Objects.requireNonNull(request, "request"); + this.policy = Objects.requireNonNull(policy, "policy"); + this.pendingOutbounds = List.copyOf(pendingOutbounds == null ? List.of() : pendingOutbounds); + this.occupiedCount = occupiedCount; + this.missingManualLanes = policy.manualReservedLanes().stream() + .map(ManualLaneReservation::laneCode) + .collect(Collectors.toCollection(java.util.LinkedHashSet::new)); + } + + public void accept(List pageSpaces) { + InboundContext context = new InboundContext(pageSpaces, policy, pendingOutbounds, occupiedCount); + List lanes = buildLanes(context); + lanes.forEach(lane -> missingManualLanes.remove(lane.code())); + if (policy.isCommon(request.projectNo())) { + acceptCommon(context, lanes); + } else { + acceptProject(context, lanes); + } + } + + public Optional currentAssignment() { + return selected().map(candidate -> toAssignment(request, candidate)); + } + + public java.util.Set retainedLaneCodes() { + return retained.values().stream().map(candidate -> candidate.lane().code()) + .collect(Collectors.toUnmodifiableSet()); + } + + public InboundPlan finish() { + if (!missingManualLanes.isEmpty()) { + throw new IllegalArgumentException("manualReservedLanes references unknown lane " + + missingManualLanes.iterator().next()); + } + Optional candidate = selected(); + if (candidate.isPresent()) return InboundPlan.assigned(toAssignment(request, candidate.orElseThrow())); + + boolean sealed = request.batchLaneMode() == BatchLaneMode.SEALED + && !policy.isCommon(request.projectNo()); + InboundRejectionCode code = sealed ? InboundRejectionCode.NO_BATCH_COMPATIBLE_LANE + : InboundRejectionCode.NO_FEASIBLE_LOCATION; + String reason = sealed + ? "No lane can continue the same project, product and lot, and no completely empty lane remains." + : "Inbound admission ladder exhausted every legal location; no feasible location remains."; + return InboundPlan.rejected(new InboundRejection(code, reason, request.projectNo(), + request.productId(), request.lotNo(), pagedTrace(sealed))); + } + + private void acceptProject(InboundContext context, List lanes) { + retain("CONTINUE", best(lanes.stream() + .filter(lane -> lane.usableForInbound() && !lane.occupied().isEmpty()) + .map(lane -> continueCandidate(request, context, lane)).flatMap(Optional::stream).toList()), + candidateComparator()); + + int targetDepth = gradedTargetDepth(request, context); + retain("GRADED", best(emptyLaneCandidates(request, context, lanes, targetDepth, + InboundLadderRung.OPEN_GRADED)), candidateComparator()); + for (int depth : ADJACENT_DEPTH_ORDER.getOrDefault(targetDepth, List.of())) { + retain("ADJACENT:" + depth, best(emptyLaneCandidates(request, context, lanes, depth, + InboundLadderRung.OPEN_ADJACENT)), candidateComparator()); + } + + if (request.batchLaneMode() != BatchLaneMode.SEALED && request.projectNo() != null + && !policy.isIsolated(request.projectNo()) && !policy.isCommon(request.projectNo()) + && policy.allowsMixed(request.projectNo())) { + Comparator mixedOrder = Comparator.comparingInt(Candidate::remaining) + .thenComparing(Candidate::residentNewest).thenComparing(candidateComparator()); + retain("MIXED", bestMixed(request, context, lanes), mixedOrder); + } + acceptPool(context, lanes); + } + + private void acceptPool(InboundContext context, List lanes) { + List pool = lanes.stream().filter(lane -> lane.depth() == 1) + .filter(lane -> lane.spaces().stream().allMatch(space -> space.role() == SpaceRole.STORAGE)) + .toList(); + freeSinglePool += pool.stream().filter(Lane::isEmptyLane).count(); + List tiers = new ArrayList<>(); + tiers.add(new PoolTier("FLEX", InboundBorrowType.NONE)); + tiers.add(new PoolTier("CACHE", InboundBorrowType.CACHE_BORROWED)); + if (occupiedCount >= policy.schedulingPolicy().capacityFirstOccupied()) { + tiers.add(new PoolTier("RESERVE", InboundBorrowType.RESERVE_BORROWED)); + } + for (PoolTier tier : tiers) { + retain("POOL:" + tier.zone(), best(pool.stream().filter(Lane::usableForInbound) + .filter(Lane::isEmptyLane) + .filter(lane -> tier.zone().equalsIgnoreCase(lane.spaces().get(0).zoneCode())) + .filter(lane -> usableSlot(lane, lane.spaces().get(0), request, context)) + .map(lane -> score(lane, lane.spaces().get(0), request, context, + InboundLadderRung.POOL_BORROW, tier.borrowType(), null, true)).toList()), + candidateComparator()); + } + } + + private void acceptCommon(InboundContext context, List lanes) { + for (String zone : List.of("FLEX", "CACHE", "RESERVE")) { + retain("COMMON_SINGLE:" + zone, best(lanes.stream().filter(Lane::usableForInbound) + .filter(lane -> lane.depth() == 1 && lane.isEmptyLane()) + .filter(lane -> zone.equalsIgnoreCase(lane.spaces().get(0).zoneCode())) + .filter(lane -> usableSlot(lane, lane.spaces().get(0), request, context)) + .map(lane -> score(lane, lane.spaces().get(0), request, context, + InboundLadderRung.COMMON_SINGLE, InboundBorrowType.NONE, null, true)).toList()), + candidateComparator()); + } + retain("COMMON_CONTINUE", best(lanes.stream().filter(Lane::usableForInbound) + .filter(lane -> lane.depth() == 2 && !lane.occupied().isEmpty()) + .filter(lane -> lane.nextSlot().isPresent()) + .filter(lane -> lane.occupied().stream().allMatch(space -> commonCompatible(space, request, context))) + .filter(lane -> usableSlot(lane, lane.nextSlot().orElseThrow(), request, context)) + .map(lane -> score(lane, lane.nextSlot().orElseThrow(), request, context, + InboundLadderRung.COMMON_LANE_CONTINUE, InboundBorrowType.NONE, null, false)).toList()), + candidateComparator()); + retain("COMMON_OPEN", best(emptyLaneCandidates(request, context, lanes, 2, + InboundLadderRung.COMMON_LANE_OPEN)), candidateComparator()); + } + + private Optional selected() { + if (policy.isCommon(request.projectNo())) { + for (String zone : List.of("FLEX", "CACHE", "RESERVE")) { + Candidate candidate = retained.get("COMMON_SINGLE:" + zone); + if (candidate != null) return Optional.of(candidate); + } + if (retained.containsKey("COMMON_CONTINUE")) return Optional.of(retained.get("COMMON_CONTINUE")); + return Optional.ofNullable(retained.get("COMMON_OPEN")); + } + if (retained.containsKey("CONTINUE")) return Optional.of(retained.get("CONTINUE")); + if (retained.containsKey("GRADED")) return Optional.of(retained.get("GRADED")); + int targetDepth = gradedTargetDepth(request, + new InboundContext(List.of(), policy, pendingOutbounds, occupiedCount)); + if (targetDepth == 2) { + Optional pool = selectedPool(); + if (pool.isPresent()) return pool; + } + for (int depth : ADJACENT_DEPTH_ORDER.getOrDefault(targetDepth, List.of())) { + Candidate candidate = retained.get("ADJACENT:" + depth); + if (candidate != null) return Optional.of(candidate); + } + if (retained.containsKey("MIXED")) return Optional.of(retained.get("MIXED")); + return selectedPool(); + } + + private Optional selectedPool() { + if (policy.commonSinglePoolReserve() > 0 + && freeSinglePool - 1 < policy.commonSinglePoolReserve()) return Optional.empty(); + for (String zone : List.of("FLEX", "CACHE", "RESERVE")) { + Candidate candidate = retained.get("POOL:" + zone); + if (candidate != null) return Optional.of(candidate); + } + return Optional.empty(); + } + + private void retain(String key, Optional candidate, Comparator comparator) { + candidate.ifPresent(value -> retained.merge(key, value, + (current, proposed) -> comparator.compare(proposed, current) < 0 ? proposed : current)); + } + + private List pagedTrace(boolean sealed) { + if (policy.isCommon(request.projectNo())) { + return List.of( + new LadderTraceStep(InboundLadderRung.COMMON_SINGLE, + "No outbound-free and reservation-compatible FLEX, CACHE or RESERVE single slot."), + new LadderTraceStep(InboundLadderRung.COMMON_LANE_CONTINUE, + "No physically continuous outbound-free double lane contains only the same common product."), + new LadderTraceStep(InboundLadderRung.COMMON_LANE_OPEN, + "No completely empty outbound-free double lane is available.")); + } + int targetDepth = gradedTargetDepth(request, + new InboundContext(List.of(), policy, pendingOutbounds, occupiedCount)); + boolean guard = policy.commonSinglePoolReserve() > 0 + && freeSinglePool - 1 < policy.commonSinglePoolReserve(); + return List.of( + new LadderTraceStep(InboundLadderRung.CONTINUE, + "No physically continuous outbound-free lane can legally continue this project/cohort."), + new LadderTraceStep(InboundLadderRung.OPEN_GRADED, + "No completely empty legal lane at graded depth " + targetDepth + "."), + new LadderTraceStep(InboundLadderRung.OPEN_ADJACENT, + "No completely empty legal lane in adjacent order " + + ADJACENT_DEPTH_ORDER.getOrDefault(targetDepth, List.of()) + "."), + new LadderTraceStep(InboundLadderRung.MIXED_GUEST, + sealed ? "SEALED admission never mixes projects or lots." + : "No one-segment non-isolated resident lane without pending outbound can accept one outer guest."), + new LadderTraceStep(InboundLadderRung.POOL_BORROW, + guard ? "Single-pool common-parts watermark would be breached." + : "No legal FLEX/CACHE single slot, or high-water RESERVE slot, is available.")); + } + } + + private void validateManualReservations(InboundContext context) { + List laneCodes = context.spaces().stream().map(SpaceState::laneCode).distinct().toList(); + context.policy().manualReservedLanes().stream() + .filter(reservation -> !laneCodes.contains(reservation.laneCode())) + .findFirst() + .ifPresent(reservation -> { + throw new IllegalArgumentException( + "manualReservedLanes references unknown lane " + reservation.laneCode()); + }); + } + + private Optional chooseProject(InboundRequest request, InboundContext context, List lanes) { + Optional candidate = best(lanes.stream() + .filter(lane -> lane.usableForInbound() && !lane.occupied().isEmpty()) + .map(lane -> continueCandidate(request, context, lane)) + .flatMap(Optional::stream) + .toList()); + if (candidate.isPresent()) return candidate; + + int targetDepth = gradedTargetDepth(request, context); + candidate = best(emptyLaneCandidates(request, context, lanes, targetDepth, InboundLadderRung.OPEN_GRADED)); + if (candidate.isPresent()) return candidate; + + if (targetDepth == 2) { + candidate = bestPoolSingle(request, context, lanes).candidate(); + if (candidate.isPresent()) return candidate; + } + + for (int depth : ADJACENT_DEPTH_ORDER.getOrDefault(targetDepth, List.of())) { + candidate = best(emptyLaneCandidates(request, context, lanes, depth, InboundLadderRung.OPEN_ADJACENT)); + if (candidate.isPresent()) return candidate; + } + + if (request.batchLaneMode() != BatchLaneMode.SEALED + && request.projectNo() != null + && !context.policy().isIsolated(request.projectNo()) + && !context.policy().isCommon(request.projectNo()) + && context.policy().allowsMixed(request.projectNo())) { + candidate = bestMixed(request, context, lanes); + if (candidate.isPresent()) return candidate; + } + + return bestPoolSingle(request, context, lanes).candidate(); + } + + private Optional chooseCommon(InboundRequest request, InboundContext context, List lanes) { + for (String zone : List.of("FLEX", "CACHE", "RESERVE")) { + Optional single = best(lanes.stream() + .filter(Lane::usableForInbound) + .filter(lane -> lane.depth() == 1 && lane.isEmptyLane()) + .filter(lane -> zone.equalsIgnoreCase(lane.spaces().get(0).zoneCode())) + .filter(lane -> usableSlot(lane, lane.spaces().get(0), request, context)) + .map(lane -> score(lane, lane.spaces().get(0), request, context, + InboundLadderRung.COMMON_SINGLE, InboundBorrowType.NONE, null, true)) + .toList()); + if (single.isPresent()) return single; + } + + Optional continuation = best(lanes.stream() + .filter(Lane::usableForInbound) + .filter(lane -> lane.depth() == 2 && !lane.occupied().isEmpty()) + .filter(lane -> lane.nextSlot().isPresent()) + .filter(lane -> lane.occupied().stream().allMatch(space -> commonCompatible(space, request, context))) + .filter(lane -> usableSlot(lane, lane.nextSlot().orElseThrow(), request, context)) + .map(lane -> score(lane, lane.nextSlot().orElseThrow(), request, context, + InboundLadderRung.COMMON_LANE_CONTINUE, InboundBorrowType.NONE, null, false)) + .toList()); + if (continuation.isPresent()) return continuation; + + return best(emptyLaneCandidates(request, context, lanes, 2, InboundLadderRung.COMMON_LANE_OPEN)); + } + + private boolean commonCompatible(SpaceState space, InboundRequest request, InboundContext context) { + return context.policy().isCommon(space.projectNo()) + && Objects.equals(space.productId(), request.productId()); + } + + private Optional continueCandidate(InboundRequest request, InboundContext context, Lane lane) { + if (lane.segments().isEmpty()) return Optional.empty(); + Segment resident = lane.segments().get(0); + boolean residentMatch = lane.segments().size() == 1 + && Objects.equals(resident.projectNo(), request.projectNo()); + boolean guestMatch = lane.segments().size() == 2 + && Objects.equals(lane.segments().get(1).projectNo(), request.projectNo()); + if (!residentMatch && !guestMatch) return Optional.empty(); + + Optional slot = guestMatch ? lane.outerSlot() : lane.nextSlot(); + if (slot.isEmpty() || !usableSlot(lane, slot.orElseThrow(), request, context)) return Optional.empty(); + if (guestMatch && (!context.policy().allowsMixed(request.projectNo()) + || !context.policy().allowsMixed(resident.projectNo()))) { + return Optional.empty(); + } + if (request.batchLaneMode() == BatchLaneMode.SEALED && lane.occupied().stream().anyMatch(space -> + !Objects.equals(space.projectNo(), request.projectNo()) + || !Objects.equals(space.productId(), request.productId()) + || !Objects.equals(space.lotNo(), request.lotNo()))) { + return Optional.empty(); + } + return Optional.of(score(lane, slot.orElseThrow(), request, context, InboundLadderRung.CONTINUE, + guestMatch ? InboundBorrowType.MIXED_IN : InboundBorrowType.NONE, + guestMatch ? resident.projectNo() : null, false)); + } + + private List emptyLaneCandidates(InboundRequest request, InboundContext context, + List lanes, int depth, InboundLadderRung rung) { + return lanes.stream() + .filter(Lane::usableForInbound) + .filter(lane -> lane.depth() == depth && lane.isEmptyLane()) + .filter(lane -> lane.spaces().stream().allMatch(space -> space.role() == SpaceRole.STORAGE)) + .filter(lane -> usableSlot(lane, lane.spaces().get(0), request, context)) + .map(lane -> score(lane, lane.spaces().get(0), request, context, rung, + InboundBorrowType.NONE, null, true)) + .toList(); + } + + private PoolChoice bestPoolSingle(InboundRequest request, InboundContext context, List lanes) { + List pool = lanes.stream() + .filter(lane -> lane.depth() == 1) + .filter(lane -> lane.spaces().stream().allMatch(space -> space.role() == SpaceRole.STORAGE)) + .toList(); + long freeTotal = pool.stream().filter(Lane::isEmptyLane).count(); + if (context.policy().commonSinglePoolReserve() > 0 + && freeTotal - 1 < context.policy().commonSinglePoolReserve()) { + return new PoolChoice(Optional.empty(), true); + } + + List tiers = new ArrayList<>(); + tiers.add(new PoolTier("FLEX", InboundBorrowType.NONE)); + tiers.add(new PoolTier("CACHE", InboundBorrowType.CACHE_BORROWED)); + if (context.occupiedCount() >= context.policy().schedulingPolicy().capacityFirstOccupied()) { + tiers.add(new PoolTier("RESERVE", InboundBorrowType.RESERVE_BORROWED)); + } + for (PoolTier tier : tiers) { + Optional found = best(pool.stream() + .filter(Lane::usableForInbound) + .filter(Lane::isEmptyLane) + .filter(lane -> tier.zone().equalsIgnoreCase(lane.spaces().get(0).zoneCode())) + .filter(lane -> usableSlot(lane, lane.spaces().get(0), request, context)) + .map(lane -> score(lane, lane.spaces().get(0), request, context, + InboundLadderRung.POOL_BORROW, tier.borrowType(), null, true)) + .toList()); + if (found.isPresent()) return new PoolChoice(found, false); + } + return new PoolChoice(Optional.empty(), false); + } + + private Optional bestMixed(InboundRequest request, InboundContext context, List lanes) { + Comparator mixedOrder = Comparator.comparingInt(Candidate::remaining) + .thenComparing(Candidate::residentNewest) + .thenComparing(candidateComparator()); + return lanes.stream() + .filter(Lane::usableForInbound) + .filter(lane -> lane.depth() >= 2 && lane.segments().size() == 1 && lane.outerSlot().isPresent()) + .filter(lane -> lane.segments().get(0).projectNo() != null) + .filter(lane -> !Objects.equals(lane.segments().get(0).projectNo(), request.projectNo())) + .filter(lane -> !context.policy().isIsolated(lane.segments().get(0).projectNo())) + .filter(lane -> !context.policy().isCommon(lane.segments().get(0).projectNo())) + .filter(lane -> context.policy().allowsMixed(request.projectNo())) + .filter(lane -> context.policy().allowsMixed(lane.segments().get(0).projectNo())) + .filter(lane -> usableSlot(lane, lane.outerSlot().orElseThrow(), request, context)) + .map(lane -> score(lane, lane.outerSlot().orElseThrow(), request, context, + InboundLadderRung.MIXED_GUEST, InboundBorrowType.MIXED_IN, + lane.segments().get(0).projectNo(), false)) + .min(mixedOrder); + } + + private List traceFor(InboundRequest request, InboundContext context, List lanes) { + if (context.policy().isCommon(request.projectNo())) { + return List.of( + new LadderTraceStep(InboundLadderRung.COMMON_SINGLE, + "No outbound-free and reservation-compatible FLEX, CACHE or RESERVE single slot."), + new LadderTraceStep(InboundLadderRung.COMMON_LANE_CONTINUE, + "No physically continuous outbound-free double lane contains only the same common product."), + new LadderTraceStep(InboundLadderRung.COMMON_LANE_OPEN, + "No completely empty outbound-free double lane is available.")); + } + + int targetDepth = gradedTargetDepth(request, context); + PoolChoice pool = bestPoolSingle(request, context, lanes); + String poolReason = pool.guardBlocked() + ? "Single-pool common-parts watermark would be breached." + : "No legal FLEX/CACHE single slot, or high-water RESERVE slot, is available."; + return List.of( + new LadderTraceStep(InboundLadderRung.CONTINUE, + "No physically continuous outbound-free lane can legally continue this project/cohort."), + new LadderTraceStep(InboundLadderRung.OPEN_GRADED, + "No completely empty legal lane at graded depth " + targetDepth + "."), + new LadderTraceStep(InboundLadderRung.OPEN_ADJACENT, + "No completely empty legal lane in adjacent order " + ADJACENT_DEPTH_ORDER.getOrDefault(targetDepth, List.of()) + "."), + new LadderTraceStep(InboundLadderRung.MIXED_GUEST, + request.batchLaneMode() == BatchLaneMode.SEALED + ? "SEALED admission never mixes projects or lots." + : "No one-segment non-isolated resident lane without pending outbound can accept one outer guest."), + new LadderTraceStep(InboundLadderRung.POOL_BORROW, poolReason)); + } + + private int gradedTargetDepth(InboundRequest request, InboundContext context) { + if (request.expectedProjectPallets() != null) { + if (request.expectedProjectPallets() <= 2) return 2; + if (request.expectedProjectPallets() == 3) return 3; + return 5; + } + long current = context.spaces().stream() + .filter(SpaceState::occupied) + .filter(space -> !space.outboundTaskActive()) + .filter(space -> Objects.equals(space.projectNo(), request.projectNo())) + .count(); + return current <= 1 ? 2 : 5; + } + + private boolean pendingHitsPallet(InboundContext context, SpaceState pallet) { + return context.pendingOutbounds().stream().anyMatch(pending -> { + boolean exactTray = pending.trayNo() != null && !pending.trayNo().isBlank() + && Objects.equals(pending.trayNo(), pallet.trayNo()); + boolean resolvedLane = pending.hasResolvedLane() + && Objects.equals(pending.sourceLaneCode(), pallet.laneCode()); + return exactTray || resolvedLane; + }); + } + + private boolean usableSlot(Lane lane, SpaceState space, InboundRequest request, InboundContext context) { + if (!lane.usableForInbound() || !space.availableEmpty() || space.role() != SpaceRole.STORAGE) return false; + if (request.targetFloor() != null && space.floorNo() != request.targetFloor()) return false; + if (request.targetFloor() == null && !request.allowedFloors().isEmpty() + && !request.allowedFloors().contains(space.floorNo())) return false; + return !reservationBlocks(lane.code(), request.projectNo(), context.policy()); + } + + private boolean reservationBlocks(String laneCode, String projectNo, InboundPolicy policy) { + Optional reservation = policy.manualReservedLanes().stream() + .filter(item -> item.laneCode().equals(laneCode)) + .findFirst(); + if (reservation.isEmpty()) return false; + if (reservation.orElseThrow().projectNo() != null) { + return !Objects.equals(reservation.orElseThrow().projectNo(), projectNo); + } + return !policy.isIsolated(projectNo); + } + + private Candidate score(Lane lane, SpaceState space, InboundRequest request, InboundContext context, + InboundLadderRung rung, InboundBorrowType borrowType, + String mixedIntoResidentProject, boolean openedNewLane) { + long sameProject = lane.occupied().stream() + .filter(item -> request.projectNo() != null && Objects.equals(item.projectNo(), request.projectNo())) + .count(); + double fillRate = lane.spaces().isEmpty() ? 0 : (double) lane.occupied().size() / lane.spaces().size(); + double codingProgress = (space.laneCapacity() - space.groupCoding() + 1.0) / Math.max(1, space.laneCapacity()); + double zoneBonus = "MAIN".equalsIgnoreCase(space.zoneCode()) ? 8 + : "FLEX".equalsIgnoreCase(space.zoneCode()) ? 5 : 0; + double capacityScore = clamp(20 + fillRate * 52 + (sameProject > 0 ? 20 : 0) + + codingProgress * 15 + zoneBonus); + int entryFloor = Math.max(1, Math.min(8, request.entryFloor() == null ? 1 : request.entryFloor())); + int aisleDistance = Math.min(Math.abs(space.aisleNo() - 6), Math.abs(space.aisleNo() - 10)); + double efficiencyScore = clamp(105 - Math.abs(space.floorNo() - entryFloor) * 12 + - aisleDistance * 3 - numericRow(space.rowCode()) * 0.7); + SchedulingPolicy scheduling = context.policy().schedulingPolicy(); + double capacityWeight = scheduling.capacityWeight(); + double efficiencyWeight = scheduling.efficiencyWeight(); + if (context.occupiedCount() >= scheduling.capacityFirstOccupied()) { + capacityWeight = 0.8; + efficiencyWeight = 0.2; + } + double sum = capacityWeight + efficiencyWeight; + if (sum == 0) { + capacityWeight = efficiencyWeight = 0.5; + sum = 1; + } + double totalScore = capacityScore * capacityWeight / sum + efficiencyScore * efficiencyWeight / sum; + Instant residentNewest = lane.occupied().stream() + .map(SpaceState::inboundAt) + .filter(Objects::nonNull) + .max(Comparator.naturalOrder()) + .orElse(Instant.MAX); + if (lane.occupied().stream().anyMatch(item -> item.inboundAt() == null)) residentNewest = Instant.MAX; + return new Candidate(space, lane, rung, borrowType, mixedIntoResidentProject, openedNewLane, + round1(capacityScore), round1(efficiencyScore), round1(totalScore), round1(fillRate * 100), + lane.spaces().size() - lane.occupied().size(), residentNewest); + } + + private Optional best(List candidates) { + return candidates.stream().min(candidateComparator()); + } + + private Comparator candidateComparator() { + return Comparator.comparingDouble(Candidate::totalScore).reversed() + .thenComparing(Comparator.comparingDouble(Candidate::capacityScore).reversed()) + .thenComparing(candidate -> candidate.space().spaceId()); + } + + private InboundAssignment toAssignment(InboundRequest request, Candidate candidate) { + SpaceState space = candidate.space(); + String reason = "Selected the innermost legal slot " + space.spaceId() + " in lane " + + candidate.lane().code() + " at rung " + candidate.rung() + + "; fill=" + candidate.fillRatePercent() + "%, capacity=" + candidate.capacityScore() + + ", efficiency=" + candidate.efficiencyScore() + ", total=" + candidate.totalScore() + "."; + return new InboundAssignment(request.requestId(), space.spaceId(), candidate.lane().code(), + space.laneCapacity(), space.depthOrder(), candidate.rung(), candidate.borrowType(), + candidate.mixedIntoResidentProject(), candidate.capacityScore(), candidate.efficiencyScore(), + candidate.totalScore(), candidate.fillRatePercent(), request.batchLaneMode() == BatchLaneMode.SEALED, + candidate.openedNewLane(), reason); + } + + private List buildLanes(InboundContext context) { + Map> grouped = context.spaces().stream().collect(Collectors.groupingBy( + SpaceState::laneCode, LinkedHashMap::new, Collectors.toList())); + return grouped.entrySet().stream().map(entry -> analyzeLane(entry.getKey(), entry.getValue(), context)) + .toList(); + } + + private Lane analyzeLane(String code, List input, InboundContext context) { + List spaces = input.stream() + .sorted(Comparator.comparingInt(SpaceState::depthOrder).thenComparing(SpaceState::spaceId)) + .toList(); + List occupied = spaces.stream().filter(SpaceState::occupied).toList(); + boolean gapSeen = false; + boolean continuous = true; + boolean invalid = false; + for (SpaceState space : spaces) { + if (!space.occupied()) { + gapSeen = true; + } else if (gapSeen) { + continuous = false; + } + if (space.inventoryProjectConflict() + || (space.status() == SpaceStatus.EMPTY && space.hasTray())) invalid = true; + } + + List segments = new ArrayList<>(); + for (SpaceState space : occupied) { + String key = segmentKey(space, context.policy()); + if (segments.isEmpty() || !segments.get(segments.size() - 1).key().equals(key)) { + segments.add(new Segment(key, space.projectNo(), space.productId())); + } + } + int depth = spaces.stream().mapToInt(SpaceState::laneCapacity).max().orElse(0); + boolean completeTopology = spaces.size() == depth; + for (int index = 0; index < spaces.size(); index++) { + SpaceState space = spaces.get(index); + if (space.depthOrder() != index + 1 || space.laneCapacity() != depth) { + completeTopology = false; + break; + } + } + boolean corrupt = invalid || !continuous || !completeTopology || segments.size() > 2; + int maxOccupiedDepth = occupied.stream().mapToInt(SpaceState::depthOrder).max().orElse(0); + Optional immediateOuterSlot = corrupt ? Optional.empty() + : spaces.stream().filter(SpaceState::availableEmpty) + .filter(space -> space.depthOrder() == maxOccupiedDepth + 1).findFirst(); + boolean emptyLane = occupied.isEmpty() && spaces.stream().allMatch(SpaceState::availableEmpty); + boolean outboundBlocked = spaces.stream().anyMatch(SpaceState::outboundTaskActive) + || occupied.stream().anyMatch(space -> pendingHitsPallet(context, space)); + return new Lane(code, depth, spaces, occupied, segments, corrupt, outboundBlocked, + emptyLane, immediateOuterSlot, immediateOuterSlot); + } + + private String segmentKey(SpaceState space, InboundPolicy policy) { + if (space.projectNo() == null) return "P|__UNKNOWN__"; + if (policy.isCommon(space.projectNo())) { + return "C|" + space.projectNo() + "|" + Objects.toString(space.productId(), ""); + } + return "P|" + space.projectNo(); + } + + private double numericRow(String rowCode) { + try { + return Double.parseDouble(rowCode); + } catch (RuntimeException ignored) { + return 0; + } + } + + private double clamp(double value) { + return Math.max(0, Math.min(100, value)); + } + + private double round1(double value) { + return Math.round(value * 10.0) / 10.0; + } + + private record Segment(String key, String projectNo, String productId) { + } + + private record Lane( + String code, + int depth, + List spaces, + List occupied, + List segments, + boolean corrupt, + boolean outboundBlocked, + boolean isEmptyLane, + Optional nextSlot, + Optional outerSlot + ) { + private boolean usableForInbound() { + return !corrupt && !outboundBlocked; + } + } + + private record Candidate( + SpaceState space, + Lane lane, + InboundLadderRung rung, + InboundBorrowType borrowType, + String mixedIntoResidentProject, + boolean openedNewLane, + double capacityScore, + double efficiencyScore, + double totalScore, + double fillRatePercent, + int remaining, + Instant residentNewest + ) { + } + + private record PoolTier(String zone, InboundBorrowType borrowType) { + } + + private record PoolChoice(Optional candidate, boolean guardBlocked) { + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundPolicy.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundPolicy.java new file mode 100644 index 0000000..58354f1 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundPolicy.java @@ -0,0 +1,51 @@ +package com.ruoyi.algorithm.inbound; + +import com.ruoyi.algorithm.policy.SchedulingPolicy; + +import java.util.List; +import java.util.Set; + +public record InboundPolicy( + SchedulingPolicy schedulingPolicy, + Set isolatedProjects, + Set commonProjectNos, + List manualReservedLanes, + int commonSinglePoolReserve, + Set mixedDeniedProjects +) { + public InboundPolicy { + schedulingPolicy = schedulingPolicy == null ? SchedulingPolicy.ft546Defaults() : schedulingPolicy; + isolatedProjects = isolatedProjects == null ? Set.of() : Set.copyOf(isolatedProjects); + commonProjectNos = commonProjectNos == null ? Set.of("COMMON") : Set.copyOf(commonProjectNos); + manualReservedLanes = manualReservedLanes == null ? List.of() : List.copyOf(manualReservedLanes); + mixedDeniedProjects = mixedDeniedProjects == null ? Set.of() : Set.copyOf(mixedDeniedProjects); + if (commonSinglePoolReserve < 0) throw new IllegalArgumentException("commonSinglePoolReserve cannot be negative"); + long distinctLanes = manualReservedLanes.stream().map(ManualLaneReservation::laneCode).distinct().count(); + if (distinctLanes != manualReservedLanes.size()) { + throw new IllegalArgumentException("manualReservedLanes contains a duplicate lane"); + } + } + + public InboundPolicy(SchedulingPolicy schedulingPolicy, Set isolatedProjects, + Set commonProjectNos, List manualReservedLanes, + int commonSinglePoolReserve) { + this(schedulingPolicy, isolatedProjects, commonProjectNos, manualReservedLanes, + commonSinglePoolReserve, Set.of()); + } + + public static InboundPolicy defaults() { + return new InboundPolicy(SchedulingPolicy.ft546Defaults(), Set.of(), Set.of("COMMON"), List.of(), 0); + } + + public boolean isIsolated(String projectNo) { + return projectNo != null && isolatedProjects.contains(projectNo); + } + + public boolean isCommon(String projectNo) { + return projectNo != null && commonProjectNos.contains(projectNo); + } + + public boolean allowsMixed(String projectNo) { + return projectNo != null && !mixedDeniedProjects.contains(projectNo); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundRejection.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundRejection.java new file mode 100644 index 0000000..bba17fd --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundRejection.java @@ -0,0 +1,16 @@ +package com.ruoyi.algorithm.inbound; + +import java.util.List; + +public record InboundRejection( + InboundRejectionCode code, + String reason, + String projectNo, + String productId, + String lotNo, + List ladderTrace +) { + public InboundRejection { + ladderTrace = List.copyOf(ladderTrace); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundRejectionCode.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundRejectionCode.java new file mode 100644 index 0000000..14ff868 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundRejectionCode.java @@ -0,0 +1,6 @@ +package com.ruoyi.algorithm.inbound; + +public enum InboundRejectionCode { + NO_FEASIBLE_LOCATION, + NO_BATCH_COMPATIBLE_LANE +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundRequest.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundRequest.java new file mode 100644 index 0000000..95ac54e --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/InboundRequest.java @@ -0,0 +1,26 @@ +package com.ruoyi.algorithm.inbound; + +import java.util.Set; + +public record InboundRequest( + String requestId, + String trayNo, + String projectNo, + String productId, + String lotNo, + Integer expectedProjectPallets, + Integer entryFloor, + Integer targetFloor, + Set allowedFloors, + BatchLaneMode batchLaneMode +) { + public InboundRequest { + if (requestId == null || requestId.isBlank()) throw new IllegalArgumentException("requestId is required"); + if (trayNo == null || trayNo.isBlank()) throw new IllegalArgumentException("trayNo is required"); + if (expectedProjectPallets != null && expectedProjectPallets <= 0) { + throw new IllegalArgumentException("expectedProjectPallets must be positive"); + } + allowedFloors = allowedFloors == null ? Set.of() : Set.copyOf(allowedFloors); + batchLaneMode = batchLaneMode == null ? BatchLaneMode.OPEN : batchLaneMode; + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/LadderTraceStep.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/LadderTraceStep.java new file mode 100644 index 0000000..809d519 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/LadderTraceStep.java @@ -0,0 +1,4 @@ +package com.ruoyi.algorithm.inbound; + +public record LadderTraceStep(InboundLadderRung rung, String reason) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/ManualLaneReservation.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/ManualLaneReservation.java new file mode 100644 index 0000000..af41f5f --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/ManualLaneReservation.java @@ -0,0 +1,9 @@ +package com.ruoyi.algorithm.inbound; + +public record ManualLaneReservation(String laneCode, String projectNo) { + public ManualLaneReservation { + if (laneCode == null || laneCode.isBlank()) { + throw new IllegalArgumentException("laneCode is required"); + } + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/PendingOutbound.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/PendingOutbound.java new file mode 100644 index 0000000..fe9971d --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/inbound/PendingOutbound.java @@ -0,0 +1,17 @@ +package com.ruoyi.algorithm.inbound; + +public record PendingOutbound(String projectNo, String productId, String trayNo, + String sourceLaneCode, String sourceResolution) { + public PendingOutbound(String projectNo, String productId, String trayNo) { + this(projectNo, productId, trayNo, null, "UNRESOLVED"); + } + + public boolean hasResolvedLane() { + if (sourceLaneCode == null || sourceLaneCode.isBlank() + || sourceResolution == null || sourceResolution.isBlank()) { + return false; + } + return !"UNRESOLVED".equalsIgnoreCase(sourceResolution) + && !"AMBIGUOUS_TRAY".equalsIgnoreCase(sourceResolution); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/AlgorithmConfiguration.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/AlgorithmConfiguration.java new file mode 100644 index 0000000..894a7c1 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/AlgorithmConfiguration.java @@ -0,0 +1,45 @@ +package com.ruoyi.algorithm.integration; + +import com.ruoyi.algorithm.inbound.InboundPlanner; +import com.ruoyi.algorithm.outbound.OutboundPlanner; +import com.ruoyi.algorithm.repository.JdbcWarehouseRepository; +import com.ruoyi.algorithm.repository.RepositoryDialect; +import com.ruoyi.algorithm.repository.WarehouseRepository; +import com.ruoyi.algorithm.service.WarehouseApplicationService; +import com.ruoyi.algorithm.tidy.TidyPlanner; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; + +@Configuration +@EnableConfigurationProperties(AlgorithmProperties.class) +public class AlgorithmConfiguration { + + @Bean + WarehouseRepository algorithmWarehouseRepository(DataSource dataSource, AlgorithmProperties properties, + PlatformTransactionManager transactionManager) { + if (transactionManager instanceof DataSourceTransactionManager dataSourceTransactionManager + && dataSourceTransactionManager.getDataSource() != dataSource) { + throw new IllegalStateException("Algorithm repository and WMS must use the same DataSource"); + } + return new JdbcWarehouseRepository(dataSource, RepositoryDialect.sqlServer(), + properties.isDatabaseWritesEnabled(), transactionManager); + } + + @Bean + WarehouseApplicationService algorithmApplicationService(WarehouseRepository algorithmWarehouseRepository, + AlgorithmProperties properties) { + return new WarehouseApplicationService(algorithmWarehouseRepository, new InboundPlanner(), + new OutboundPlanner(), new TidyPlanner(), properties.getPageSize()); + } + + @Bean + SchedulingFacade schedulingFacade(WarehouseApplicationService algorithmApplicationService, + AlgorithmProperties properties) { + return new SchedulingFacade(algorithmApplicationService, properties); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/SchedulingDecisionStatus.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/SchedulingDecisionStatus.java new file mode 100644 index 0000000..621c069 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/SchedulingDecisionStatus.java @@ -0,0 +1,8 @@ +package com.ruoyi.algorithm.integration; + +public enum SchedulingDecisionStatus { + READY, + WAITING, + REJECTED, + TECHNICAL_ERROR +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/SchedulingFacade.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/SchedulingFacade.java new file mode 100644 index 0000000..a684c9f --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/SchedulingFacade.java @@ -0,0 +1,82 @@ +package com.ruoyi.algorithm.integration; + +import com.ruoyi.algorithm.inbound.InboundRequest; +import com.ruoyi.algorithm.outbound.OutboundPlan; +import com.ruoyi.algorithm.outbound.OutboundRequest; +import com.ruoyi.algorithm.repository.DeepWorkflowMutationResult; +import com.ruoyi.algorithm.repository.ReservationResult; +import com.ruoyi.algorithm.service.InboundPlanningResult; +import com.ruoyi.algorithm.service.InboundReservationOutcome; +import com.ruoyi.algorithm.service.WarehouseApplicationService; +import com.ruoyi.algorithm.tidy.TidyPlan; + +import java.time.Instant; + +import java.util.Objects; + +public final class SchedulingFacade { + private final WarehouseApplicationService applicationService; + private final AlgorithmProperties properties; + private final SchedulingRoutingPolicy routingPolicy; + + public SchedulingFacade(WarehouseApplicationService applicationService, AlgorithmProperties properties) { + this.applicationService = Objects.requireNonNull(applicationService, "applicationService"); + this.properties = Objects.requireNonNull(properties, "properties"); + this.routingPolicy = new SchedulingRoutingPolicy(properties.getMode(), + properties.isLegacyFallbackOnTechnicalError()); + } + + public SchedulingRoutingPolicy routingPolicy() { + return routingPolicy; + } + + public String defaultWarehouseId() { + return properties.getWarehouseId(); + } + + public InboundPlanningResult planInbound(String warehouseId, InboundRequest request) { + requireAlgorithmMode(); + return applicationService.planInbound(warehouseId, request); + } + + public InboundReservationOutcome reserveInbound(String reservationId, String warehouseId, + String projectNo, InboundPlanningResult plan) { + requireActiveMode(); + return applicationService.reserveInbound(reservationId, warehouseId, projectNo, plan); + } + + public OutboundPlan planOutbound(String warehouseId, OutboundRequest request) { + requireAlgorithmMode(); + return applicationService.planOutbound(warehouseId, request); + } + + public TidyPlan planTidy(String warehouseId, Instant now) { + requireAlgorithmMode(); + return applicationService.planTidy(warehouseId, now); + } + + public ReservationResult releaseInboundReservation(String warehouseId, String reservationId) { + return applicationService.releaseReservation(warehouseId, reservationId); + } + + public DeepWorkflowMutationResult acquireDeepWorkflowLock(String warehouseId, String requestId, int floorNo) { + requireActiveMode(); + return applicationService.acquireDeepWorkflowLock(warehouseId, requestId, floorNo); + } + + public DeepWorkflowMutationResult releaseDeepWorkflowLock(String warehouseId, String requestId, int floorNo) { + return applicationService.releaseDeepWorkflowLock(warehouseId, requestId, floorNo); + } + + private void requireAlgorithmMode() { + if (!routingPolicy.runAlgorithm()) { + throw new IllegalStateException("Java scheduling is disabled in LEGACY mode"); + } + } + + private void requireActiveMode() { + if (!routingPolicy.algorithmOwnsDecision()) { + throw new IllegalStateException("Algorithm writes require ACTIVE mode"); + } + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/SchedulingMode.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/SchedulingMode.java new file mode 100644 index 0000000..e5a7395 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/SchedulingMode.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.integration; + +public enum SchedulingMode { + LEGACY, + SHADOW, + ACTIVE +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/SchedulingRoutingPolicy.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/SchedulingRoutingPolicy.java new file mode 100644 index 0000000..89e4858 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/integration/SchedulingRoutingPolicy.java @@ -0,0 +1,27 @@ +package com.ruoyi.algorithm.integration; + +import java.util.Objects; + +public record SchedulingRoutingPolicy(SchedulingMode mode, boolean legacyFallbackOnTechnicalError) { + + public SchedulingRoutingPolicy { + mode = Objects.requireNonNull(mode, "mode"); + } + + public boolean runAlgorithm() { + return mode != SchedulingMode.LEGACY; + } + + public boolean algorithmOwnsDecision() { + return mode == SchedulingMode.ACTIVE; + } + + public boolean runLegacy(SchedulingDecisionStatus status) { + Objects.requireNonNull(status, "status"); + return switch (mode) { + case LEGACY, SHADOW -> true; + case ACTIVE -> status == SchedulingDecisionStatus.TECHNICAL_ERROR + && legacyFallbackOnTechnicalError; + }; + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/model/LaneState.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/model/LaneState.java new file mode 100644 index 0000000..09b878b --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/model/LaneState.java @@ -0,0 +1,19 @@ +package com.ruoyi.algorithm.model; + +import java.util.List; +import java.util.Optional; + +public record LaneState( + List spaces, + boolean physicallyContinuous, + boolean corrupt, + int segmentCount, + Optional residentProjectNo, + Optional guestProjectNo, + Optional nextSlot, + Optional outerSlot +) { + public LaneState { + spaces = List.copyOf(spaces); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/model/SpaceRole.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/model/SpaceRole.java new file mode 100644 index 0000000..d64e94e --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/model/SpaceRole.java @@ -0,0 +1,8 @@ +package com.ruoyi.algorithm.model; + +public enum SpaceRole { + STORAGE, + RELOCATION_BUFFER, + OUTBOUND_CACHE, + PROTECTED_CORE +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/model/SpaceState.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/model/SpaceState.java new file mode 100644 index 0000000..07b8505 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/model/SpaceState.java @@ -0,0 +1,54 @@ +package com.ruoyi.algorithm.model; + +import java.time.Instant; + +public record SpaceState( + String spaceId, + String zoneCode, + String laneCode, + int depthOrder, + int laneCapacity, + int floorNo, + int aisleNo, + int groupCoding, + String rowCode, + SpaceRole role, + SpaceStatus status, + boolean outboundTaskActive, + boolean inventoryProjectConflict, + String trayNo, + String projectNo, + String productId, + String lotNo, + Instant inboundAt, + Instant outboundAt, + boolean reserved, + String rowVersion, + boolean physicalStockPresent +) { + public SpaceState(String spaceId, String zoneCode, String laneCode, int depthOrder, int laneCapacity, + int floorNo, int aisleNo, int groupCoding, String rowCode, SpaceRole role, + SpaceStatus status, boolean outboundTaskActive, boolean inventoryProjectConflict, + String trayNo, String projectNo, String productId, String lotNo, Instant inboundAt, + Instant outboundAt, boolean reserved, String rowVersion) { + this(spaceId, zoneCode, laneCode, depthOrder, laneCapacity, floorNo, aisleNo, groupCoding, rowCode, + role, status, outboundTaskActive, inventoryProjectConflict, trayNo, projectNo, productId, + lotNo, inboundAt, outboundAt, reserved, rowVersion, false); + } + + public boolean hasTray() { + return trayNo != null && !trayNo.isBlank(); + } + + public boolean occupied() { + return status == SpaceStatus.OCCUPIED || hasTray() || physicalStockPresent; + } + + public boolean availableEmpty() { + return status == SpaceStatus.EMPTY && !reserved && !hasTray() && !physicalStockPresent; + } + + public boolean outboundSelectable() { + return status == SpaceStatus.OCCUPIED && !reserved && hasTray(); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/model/SpaceStatus.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/model/SpaceStatus.java new file mode 100644 index 0000000..8878d05 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/model/SpaceStatus.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.model; + +public enum SpaceStatus { + EMPTY, + OCCUPIED, + DISABLED +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/FifoDecision.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/FifoDecision.java new file mode 100644 index 0000000..e0c6a97 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/FifoDecision.java @@ -0,0 +1,25 @@ +package com.ruoyi.algorithm.outbound; + +import java.time.Instant; +import java.util.Optional; + +public record FifoDecision( + boolean fifoApplied, + String fifoMode, + Integer fifoRank, + Instant oldestInboundTime, + Instant selectedInboundTime, + int fifoDeviationMinutes, + boolean fifoViolation, + String reason, + Optional warning +) { + public FifoDecision { + warning = warning == null ? Optional.empty() : warning; + } + + public static FifoDecision off() { + return new FifoDecision(false, "OFF", null, null, null, 0, false, + "FIFO is disabled", Optional.empty()); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/FifoWarning.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/FifoWarning.java new file mode 100644 index 0000000..544fdbe --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/FifoWarning.java @@ -0,0 +1,4 @@ +package com.ruoyi.algorithm.outbound; + +public record FifoWarning(String code, String message) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundAssignment.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundAssignment.java new file mode 100644 index 0000000..828f66c --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundAssignment.java @@ -0,0 +1,29 @@ +package com.ruoyi.algorithm.outbound; + +import java.util.List; +import java.util.Optional; + +public record OutboundAssignment( + String requestId, + String trayNo, + String projectNo, + String productId, + String sourceSpaceId, + int sourceFloor, + boolean wholeTray, + List blockerSpaceIds, + List blockingTrayNos, + boolean laneReleasing, + double capacityScore, + double efficiencyScore, + double totalScore, + FifoDecision fifo, + Optional workflow, + String reason +) { + public OutboundAssignment { + blockerSpaceIds = List.copyOf(blockerSpaceIds); + blockingTrayNos = List.copyOf(blockingTrayNos); + workflow = workflow == null ? Optional.empty() : workflow; + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundCapacityMode.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundCapacityMode.java new file mode 100644 index 0000000..5e6ab38 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundCapacityMode.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.outbound; + +public enum OutboundCapacityMode { + BALANCED, + WARNING, + CAPACITY_FIRST +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundContext.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundContext.java new file mode 100644 index 0000000..f97abce --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundContext.java @@ -0,0 +1,33 @@ +package com.ruoyi.algorithm.outbound; + +import com.ruoyi.algorithm.model.SpaceState; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +public record OutboundContext( + List spaces, + Map rawInboundTimes, + OutboundCapacityMode capacityMode, + Set activeDeepWorkflowFloors +) { + public OutboundContext { + spaces = List.copyOf(spaces); + rawInboundTimes = Map.copyOf(rawInboundTimes); + capacityMode = capacityMode == null ? OutboundCapacityMode.BALANCED : capacityMode; + activeDeepWorkflowFloors = activeDeepWorkflowFloors == null ? Set.of() : Set.copyOf(activeDeepWorkflowFloors); + } + + public OutboundContext(List spaces, Map rawInboundTimes, + OutboundCapacityMode capacityMode) { + this(spaces, rawInboundTimes, capacityMode, Set.of()); + } + + public String rawInboundTime(SpaceState space) { + if (rawInboundTimes.containsKey(space.spaceId())) { + return rawInboundTimes.get(space.spaceId()); + } + return space.inboundAt() == null ? null : space.inboundAt().toString(); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundError.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundError.java new file mode 100644 index 0000000..5623e17 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundError.java @@ -0,0 +1,9 @@ +package com.ruoyi.algorithm.outbound; + +import java.util.Map; + +public record OutboundError(OutboundErrorCode code, String message, Map details) { + public OutboundError { + details = Map.copyOf(details); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundErrorCode.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundErrorCode.java new file mode 100644 index 0000000..21b4ad3 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundErrorCode.java @@ -0,0 +1,12 @@ +package com.ruoyi.algorithm.outbound; + +public enum OutboundErrorCode { + STOCK_NOT_FOUND, + AMBIGUOUS_TRAY, + OUTBOUND_SCOPE_REQUIRED, + FIFO_INVALID_MODE, + FIFO_INVALID_TOLERANCE, + FIFO_SCOPE_REQUIRED, + FIFO_DATA_MISSING, + FIFO_INVALID_TIME +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundPlan.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundPlan.java new file mode 100644 index 0000000..a84bc9d --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundPlan.java @@ -0,0 +1,32 @@ +package com.ruoyi.algorithm.outbound; + +import java.util.Optional; + +public record OutboundPlan( + OutboundPlanStatus status, + Optional assignment, + Optional waiting, + Optional error, + TaskCountEstimate taskCountEstimate +) { + public OutboundPlan { + assignment = assignment == null ? Optional.empty() : assignment; + waiting = waiting == null ? Optional.empty() : waiting; + error = error == null ? Optional.empty() : error; + } + + public static OutboundPlan ready(OutboundAssignment assignment, TaskCountEstimate estimate) { + return new OutboundPlan(OutboundPlanStatus.READY, Optional.of(assignment), Optional.empty(), + Optional.empty(), estimate); + } + + public static OutboundPlan waiting(OutboundWaiting waiting) { + return new OutboundPlan(OutboundPlanStatus.WAITING, Optional.empty(), Optional.of(waiting), + Optional.empty(), TaskCountEstimate.zero()); + } + + public static OutboundPlan error(OutboundError error) { + return new OutboundPlan(OutboundPlanStatus.ERROR, Optional.empty(), Optional.empty(), + Optional.of(error), TaskCountEstimate.zero()); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundPlanStatus.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundPlanStatus.java new file mode 100644 index 0000000..91e5a30 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundPlanStatus.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.outbound; + +public enum OutboundPlanStatus { + READY, + WAITING, + ERROR +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundPlanner.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundPlanner.java new file mode 100644 index 0000000..421f917 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundPlanner.java @@ -0,0 +1,324 @@ +package com.ruoyi.algorithm.outbound; + +import com.ruoyi.algorithm.model.SpaceRole; +import com.ruoyi.algorithm.model.SpaceState; + +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + +public final class OutboundPlanner { + + public OutboundPlan plan(OutboundRequest request, OutboundContext context) { + String mode = normalizedMode(request.fifoMode()); + if (!List.of("OFF", "STRICT", "FLEXIBLE").contains(mode)) { + return error(OutboundErrorCode.FIFO_INVALID_MODE, "Unsupported FIFO mode", + Map.of("fifoMode", String.valueOf(request.fifoMode()))); + } + int tolerance = request.fifoToleranceMinutes() == null ? 0 : request.fifoToleranceMinutes(); + if (tolerance < 0) { + return error(OutboundErrorCode.FIFO_INVALID_TOLERANCE, + "FIFO tolerance must be a non-negative integer", Map.of("fifoToleranceMinutes", tolerance)); + } + if (blank(request.trayNo()) && blank(request.projectNo())) { + return error(OutboundErrorCode.OUTBOUND_SCOPE_REQUIRED, + "Outbound without a specified tray requires projectNo", Map.of("requestId", request.requestId())); + } + + List physicalMatches = context.spaces().stream() + .filter(SpaceState::occupied) + .filter(space -> matchesRequest(space, request)) + .toList(); + if (physicalMatches.isEmpty()) { + return error(OutboundErrorCode.STOCK_NOT_FOUND, "No matching stock was found", + Map.of("requestId", request.requestId())); + } + if (!blank(request.trayNo()) && physicalMatches.stream().noneMatch(SpaceState::outboundSelectable)) { + return unavailableSource(physicalMatches.get(0)); + } + List businessMatches = physicalMatches.stream() + .filter(SpaceState::outboundSelectable) + .toList(); + if (businessMatches.isEmpty()) { + return unavailableSource(physicalMatches.get(0)); + } + + Selection selection = mode.equals("OFF") + ? selectOff(businessMatches, request, context) + : selectFifo(businessMatches, request, context, mode, tolerance); + if (selection.error() != null) return OutboundPlan.error(selection.error()); + + SpaceState source = selection.source(); + List blockers = actualBlockers(source, context.spaces()); + List unavailableBlockers = blockers.stream() + .filter(blocker -> !blocker.outboundSelectable()) + .toList(); + if (!unavailableBlockers.isEmpty()) { + return OutboundPlan.waiting(new OutboundWaiting(OutboundWaitingCode.WAITING_CHANNEL, + blockers.size(), 0, + "A physical outer pallet is allocated, inspected, locked, or reserved; wait and recalculate", + true, Map.of("sourceSpaceId", source.spaceId(), "laneCode", source.laneCode(), + "blockingSpaceIds", blockers.stream().map(SpaceState::spaceId).toList(), + "blockingTrayNos", blockers.stream().map(SpaceState::trayNo).toList(), + "unavailableBlockingSpaceIds", unavailableBlockers.stream().map(SpaceState::spaceId).toList()))); + } + List buffers = availableBuffers(source.floorNo(), context.spaces()); + if (!blockers.isEmpty() && context.activeDeepWorkflowFloors().contains(source.floorNo())) { + return OutboundPlan.waiting(new OutboundWaiting( + OutboundWaitingCode.WAITING_RELOCATION_BUFFER, + blockers.size(), buffers.size(), + "An active same-floor deep workflow owns the relocation buffer; wait and recalculate", + true, Map.of("floor", source.floorNo(), "sourceSpaceId", source.spaceId(), + "laneCode", source.laneCode()))); + } + if (buffers.size() < blockers.size()) { + List blockerIds = blockers.stream().map(SpaceState::spaceId).toList(); + List blockerTrays = blockers.stream().map(SpaceState::trayNo).toList(); + Map details = new HashMap<>(); + details.put("floor", source.floorNo()); + details.put("required", blockers.size()); + details.put("available", buffers.size()); + details.put("sourceSpaceId", source.spaceId()); + details.put("laneCode", source.laneCode()); + details.put("blockingSpaceIds", blockerIds); + details.put("blockingTrayNos", blockerTrays); + return OutboundPlan.waiting(new OutboundWaiting( + OutboundWaitingCode.WAITING_RELOCATION_BUFFER, + blockers.size(), buffers.size(), + "Insufficient same-floor relocation buffer; wait and recalculate", true, details)); + } + + boolean laneReleasing = context.capacityMode() != OutboundCapacityMode.BALANCED + && occupiedInLane(source, context.spaces()) == 1; + Optional workflow = blockers.isEmpty() + ? Optional.empty() + : Optional.of(buildWorkflow(request, source, blockers, buffers.subList(0, blockers.size()), context.spaces())); + OutboundAssignment assignment = new OutboundAssignment( + request.requestId(), source.trayNo(), source.projectNo(), source.productId(), source.spaceId(), + source.floorNo(), request.wholeTrayOrDefault(), blockers.stream().map(SpaceState::spaceId).toList(), + blockers.stream().map(SpaceState::trayNo).toList(), laneReleasing, 100.0, + efficiencyScore(source, request, context), 100.0, selection.fifo(), workflow, + "Outbound " + source.spaceId() + " with " + blockers.size() + " blocking tray(s)"); + TaskCountEstimate estimate = new TaskCountEstimate(0, 1, blockers.size() * 2, + source.floorNo() == request.exitFloorOrDefault() ? 0 : 1); + return OutboundPlan.ready(assignment, estimate); + } + + private Selection selectOff(List matches, OutboundRequest request, OutboundContext context) { + Comparator comparator = Comparator + .comparingInt((SpaceState space) -> actualBlockers(space, context.spaces()).size()) + .thenComparingInt(space -> laneReleaseRank(space, context)) + .thenComparingInt(SpaceState::floorNo) + .thenComparing(SpaceState::spaceId); + return new Selection(matches.stream().min(comparator).orElseThrow(), FifoDecision.off(), null); + } + + private Selection selectFifo(List requestMatches, OutboundRequest request, + OutboundContext context, String mode, int tolerance) { + SpaceState specified = blank(request.trayNo()) ? null : requestMatches.get(0); + String project = specified == null ? request.projectNo() : specified.projectNo(); + String product = specified == null ? request.productId() : specified.productId(); + if (blank(project)) { + return failed(OutboundErrorCode.FIFO_SCOPE_REQUIRED, + "FIFO scope requires a project or a tray that identifies one", Map.of("requestId", request.requestId())); + } + List scope = context.spaces().stream() + .filter(SpaceState::occupied) + .filter(space -> project.equals(space.projectNo())) + .filter(space -> blank(product) || product.equals(space.productId())) + .toList(); + List missing = scope.stream() + .filter(space -> blank(context.rawInboundTime(space))) + .map(SpaceState::spaceId) + .sorted() + .toList(); + if (!missing.isEmpty()) { + return failed(OutboundErrorCode.FIFO_DATA_MISSING, + "FIFO scope contains stock without inbound time", Map.of("spaceIds", missing)); + } + + List timed = new ArrayList<>(); + for (SpaceState space : scope) { + String raw = context.rawInboundTime(space); + Instant timestamp; + try { + timestamp = OffsetDateTime.parse(raw).toInstant(); + } catch (DateTimeParseException first) { + try { + timestamp = Instant.parse(raw); + } catch (DateTimeParseException second) { + return failed(OutboundErrorCode.FIFO_INVALID_TIME, "Stock has an invalid inbound time", + Map.of("spaceId", space.spaceId(), "inboundTime", raw)); + } + } + timed.add(new TimedStock(space, timestamp, actualBlockers(space, context.spaces()).size(), + laneReleaseRank(space, context), efficiencyScore(space, request, context))); + } + Instant oldest = timed.stream().map(TimedStock::timestamp).min(Instant::compareTo).orElseThrow(); + Comparator costComparator = Comparator.comparingInt(TimedStock::blockerCount) + .thenComparingInt(TimedStock::releaseRank) + .thenComparing(Comparator.comparingInt(TimedStock::efficiencyScore).reversed()) + .thenComparing(TimedStock::timestamp) + .thenComparing(item -> item.space().spaceId()); + + TimedStock selected; + if (specified != null) { + selected = timed.stream().filter(item -> item.space().spaceId().equals(specified.spaceId())) + .findFirst().orElseThrow(); + } else if (mode.equals("STRICT")) { + selected = timed.stream().filter(item -> item.timestamp().equals(oldest)).min(costComparator).orElseThrow(); + } else { + Instant latest = oldest.plus(tolerance, ChronoUnit.MINUTES); + selected = timed.stream().filter(item -> !item.timestamp().isAfter(latest)).min(costComparator).orElseThrow(); + } + + int rank = 1 + (int) timed.stream().filter(item -> item.timestamp().isBefore(selected.timestamp())).count(); + int deviation = Math.toIntExact(ChronoUnit.MINUTES.between(oldest, selected.timestamp())); + boolean overridden = specified != null; + boolean violation = overridden && selected.timestamp().isAfter(oldest); + Optional warning = overridden + ? Optional.of(new FifoWarning("FIFO_OVERRIDDEN_BY_TRAY", violation + ? "Specified tray is not the oldest stock; FIFO was explicitly overridden" + : "Specified tray is in the oldest FIFO cohort")) + : Optional.empty(); + String reason = overridden + ? "Specified tray retained; real FIFO rank reported" + : mode.equals("STRICT") + ? "Global oldest stock selected" + : "Lowest handling cost selected inside the FIFO tolerance window"; + return new Selection(selected.space(), new FifoDecision(true, mode, rank, oldest, selected.timestamp(), + deviation, violation, reason, warning), null); + } + + private OutboundWorkflow buildWorkflow(OutboundRequest request, SpaceState source, List blockers, + List buffers, List spaces) { + List drafts = new ArrayList<>(); + for (int index = 0; index < blockers.size(); index++) { + drafts.add(new DraftStep(id(request.requestId(), "MOVE-OUT", index), OutboundWorkflowPhase.MOVE_OUT, + blockers.get(index).spaceId(), buffers.get(index).spaceId())); + } + drafts.add(new DraftStep(id(request.requestId(), "OUTBOUND", 0), OutboundWorkflowPhase.OUTBOUND, + source.spaceId(), "DIRECT_OUT")); + + List ascending = new ArrayList<>(blockers); + ascending.sort(Comparator.comparingInt(SpaceState::groupCoding).thenComparing(SpaceState::spaceId)); + List compactTargets = spaces.stream() + .filter(space -> space.laneCode().equals(source.laneCode())) + .filter(space -> space.groupCoding() >= source.groupCoding()) + .sorted(Comparator.comparingInt(SpaceState::groupCoding).thenComparing(SpaceState::spaceId)) + .limit(blockers.size()) + .toList(); + for (int index = 0; index < ascending.size(); index++) { + SpaceState blocker = ascending.get(index); + int bufferIndex = blockers.indexOf(blocker); + String target = request.wholeTrayOrDefault() ? compactTargets.get(index).spaceId() : blocker.spaceId(); + drafts.add(new DraftStep(id(request.requestId(), "RESTORE", index), OutboundWorkflowPhase.RESTORE, + buffers.get(bufferIndex).spaceId(), target)); + } + + List steps = new ArrayList<>(); + for (int index = 0; index < drafts.size(); index++) { + DraftStep draft = drafts.get(index); + steps.add(new OutboundWorkflowStep(draft.assignmentId(), draft.phase(), draft.sourceSpaceId(), + draft.targetSpaceId(), index + 1, drafts.size(), index == 0 ? null : drafts.get(index - 1).assignmentId())); + } + List laneLocks = spaces.stream() + .filter(space -> space.laneCode().equals(source.laneCode())) + .sorted(Comparator.comparingInt(SpaceState::groupCoding).thenComparing(SpaceState::spaceId)) + .map(SpaceState::spaceId) + .toList(); + return new OutboundWorkflow(request.requestId(), source.spaceId(), source.laneCode(), source.floorNo(), steps, + laneLocks, buffers.stream().map(SpaceState::spaceId).toList(), "RELEASE_AFTER_FINAL_RESTORE"); + } + + private List actualBlockers(SpaceState source, List spaces) { + return spaces.stream() + .filter(space -> space.laneCode().equals(source.laneCode())) + .filter(space -> space.groupCoding() > source.groupCoding()) + .filter(SpaceState::occupied) + .sorted(Comparator.comparingInt(SpaceState::groupCoding).reversed() + .thenComparing(SpaceState::spaceId)) + .toList(); + } + + private List availableBuffers(int floor, List spaces) { + return spaces.stream() + .filter(space -> space.floorNo() == floor) + .filter(space -> space.role() == SpaceRole.RELOCATION_BUFFER) + .filter(SpaceState::availableEmpty) + .sorted(Comparator.comparing(SpaceState::spaceId)) + .toList(); + } + + private boolean matchesRequest(SpaceState space, OutboundRequest request) { + if (!blank(request.trayNo())) return request.trayNo().equals(space.trayNo()); + return request.projectNo().equals(space.projectNo()) + && (blank(request.productId()) || request.productId().equals(space.productId())); + } + + private int laneReleaseRank(SpaceState space, OutboundContext context) { + return context.capacityMode() != OutboundCapacityMode.BALANCED + && occupiedInLane(space, context.spaces()) == 1 ? 0 : 1; + } + + private int occupiedInLane(SpaceState source, List spaces) { + return (int) spaces.stream() + .filter(space -> space.laneCode().equals(source.laneCode())) + .filter(SpaceState::occupied) + .count(); + } + + private int efficiencyScore(SpaceState space, OutboundRequest request, OutboundContext context) { + return 100 - Math.abs(space.floorNo() - request.exitFloorOrDefault()) * 12 + - actualBlockers(space, context.spaces()).size() * 10; + } + + private OutboundPlan error(OutboundErrorCode code, String message, Map details) { + return OutboundPlan.error(new OutboundError(code, message, details)); + } + + private OutboundPlan unavailableSource(SpaceState source) { + Map details = new HashMap<>(); + details.put("sourceSpaceId", source.spaceId()); + details.put("laneCode", source.laneCode()); + if (!blank(source.trayNo())) details.put("trayNo", source.trayNo()); + return OutboundPlan.waiting(new OutboundWaiting(OutboundWaitingCode.WAITING_CHANNEL, 0, 0, + "Requested stock is allocated, inspected, locked, or reserved; wait and recalculate", true, + details)); + } + + private Selection failed(OutboundErrorCode code, String message, Map details) { + return new Selection(null, null, new OutboundError(code, message, details)); + } + + private String normalizedMode(String value) { + return blank(value) ? "OFF" : value.trim().toUpperCase(Locale.ROOT); + } + + private String id(String requestId, String phase, int index) { + return requestId + "-" + phase + "-" + String.format(Locale.ROOT, "%02d", index + 1); + } + + private boolean blank(String value) { + return value == null || value.isBlank(); + } + + private record Selection(SpaceState source, FifoDecision fifo, OutboundError error) { + } + + private record TimedStock(SpaceState space, Instant timestamp, int blockerCount, int releaseRank, + int efficiencyScore) { + } + + private record DraftStep(String assignmentId, OutboundWorkflowPhase phase, String sourceSpaceId, + String targetSpaceId) { + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundRequest.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundRequest.java new file mode 100644 index 0000000..64db789 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundRequest.java @@ -0,0 +1,20 @@ +package com.ruoyi.algorithm.outbound; + +public record OutboundRequest( + String requestId, + String trayNo, + String projectNo, + String productId, + String fifoMode, + Integer fifoToleranceMinutes, + Integer exitFloor, + Boolean wholeTray +) { + public boolean wholeTrayOrDefault() { + return wholeTray == null || wholeTray; + } + + public int exitFloorOrDefault() { + return exitFloor == null ? 1 : exitFloor; + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWaiting.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWaiting.java new file mode 100644 index 0000000..2d6096e --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWaiting.java @@ -0,0 +1,16 @@ +package com.ruoyi.algorithm.outbound; + +import java.util.Map; + +public record OutboundWaiting( + OutboundWaitingCode code, + int required, + int available, + String reason, + boolean retryable, + Map details +) { + public OutboundWaiting { + details = Map.copyOf(details); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWaitingCode.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWaitingCode.java new file mode 100644 index 0000000..6e12728 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWaitingCode.java @@ -0,0 +1,6 @@ +package com.ruoyi.algorithm.outbound; + +public enum OutboundWaitingCode { + WAITING_RELOCATION_BUFFER, + WAITING_CHANNEL +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWorkflow.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWorkflow.java new file mode 100644 index 0000000..30ee30e --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWorkflow.java @@ -0,0 +1,20 @@ +package com.ruoyi.algorithm.outbound; + +import java.util.List; + +public record OutboundWorkflow( + String workflowId, + String sourceSpaceId, + String laneCode, + int floorNo, + List steps, + List lockedLaneSpaceIds, + List lockedBufferSpaceIds, + String lockReleaseRule +) { + public OutboundWorkflow { + steps = List.copyOf(steps); + lockedLaneSpaceIds = List.copyOf(lockedLaneSpaceIds); + lockedBufferSpaceIds = List.copyOf(lockedBufferSpaceIds); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWorkflowPhase.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWorkflowPhase.java new file mode 100644 index 0000000..72af895 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWorkflowPhase.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.outbound; + +public enum OutboundWorkflowPhase { + MOVE_OUT, + OUTBOUND, + RESTORE +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWorkflowStep.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWorkflowStep.java new file mode 100644 index 0000000..21a6df8 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/OutboundWorkflowStep.java @@ -0,0 +1,12 @@ +package com.ruoyi.algorithm.outbound; + +public record OutboundWorkflowStep( + String assignmentId, + OutboundWorkflowPhase phase, + String sourceSpaceId, + String targetSpaceId, + int workflowStep, + int workflowTotalSteps, + String dependsOnAssignmentId +) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/TaskCountEstimate.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/TaskCountEstimate.java new file mode 100644 index 0000000..fb91d4e --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/outbound/TaskCountEstimate.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.outbound; + +public record TaskCountEstimate(int inbound, int outbound, int relocation, int floorChange) { + public static TaskCountEstimate zero() { + return new TaskCountEstimate(0, 0, 0, 0); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/policy/SchedulingPolicy.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/policy/SchedulingPolicy.java new file mode 100644 index 0000000..a8f1226 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/policy/SchedulingPolicy.java @@ -0,0 +1,16 @@ +package com.ruoyi.algorithm.policy; + +public record SchedulingPolicy( + double capacityWeight, + double efficiencyWeight, + int warningOccupied, + int capacityFirstOccupied, + int maxOccupied, + int relocationBuffersPerFloor, + int outboundCachesPerFloor, + int maxTidyCandidates +) { + public static SchedulingPolicy ft546Defaults() { + return new SchedulingPolicy(0.55, 0.45, 564, 597, 615, 4, 2, 10); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/DecisionLogEntry.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/DecisionLogEntry.java new file mode 100644 index 0000000..fe28bd0 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/DecisionLogEntry.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.repository; + +import java.time.Instant; + +public record DecisionLogEntry(String decisionId, String warehouseId, String decisionType, + VersionToken inputVersion, String resultCode, String reason, Instant createdAt) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/DecisionLogRecord.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/DecisionLogRecord.java new file mode 100644 index 0000000..6ec914e --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/DecisionLogRecord.java @@ -0,0 +1,5 @@ +package com.ruoyi.algorithm.repository; + +public record DecisionLogRecord(String decisionId, String warehouseId, String decisionType, + VersionToken inputVersion, String resultCode, String reason) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/DeepWorkflowMutationResult.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/DeepWorkflowMutationResult.java new file mode 100644 index 0000000..0f1dbfe --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/DeepWorkflowMutationResult.java @@ -0,0 +1,9 @@ +package com.ruoyi.algorithm.repository; + +public record DeepWorkflowMutationResult(boolean changed, String reasonCode) { + public static DeepWorkflowMutationResult succeeded() { return new DeepWorkflowMutationResult(true, null); } + public static DeepWorkflowMutationResult unchanged() { return new DeepWorkflowMutationResult(false, null); } + public static DeepWorkflowMutationResult writesDisabled() { + return new DeepWorkflowMutationResult(false, "WRITES_DISABLED"); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/H2TopologyReadModel.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/H2TopologyReadModel.java new file mode 100644 index 0000000..03d02ca --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/H2TopologyReadModel.java @@ -0,0 +1,61 @@ +package com.ruoyi.algorithm.repository; + +import org.springframework.jdbc.core.JdbcTemplate; + +import java.util.Objects; + +final class H2TopologyReadModel { + private final JdbcTemplate jdbc; + + H2TopologyReadModel(JdbcTemplate jdbc) { + this.jdbc = Objects.requireNonNull(jdbc, "jdbc"); + } + + boolean changed(String warehouseId) { + String expectedMismatch = "WITH LANE_TOPOLOGY AS (" + + "SELECT WAREHOUSE_ID,GROUP_CODING_NO AS LANE_CODE,COUNT(*) AS LANE_DEPTH," + + "MAX(THE_COLUMN) AS COLUMN_NO,MIN(THE_PLATOON) AS ROW_NO,MIN(THE_FLOOR) AS FLOOR_NO," + + "MIN(CARGO_SPACE_ID) AS STABLE_ID FROM BAS_CARGO_SPACE WHERE WAREHOUSE_ID=? " + + "GROUP BY WAREHOUSE_ID,GROUP_CODING_NO), RANKED_LANES AS (" + + "SELECT LANE_TOPOLOGY.*,CASE WHEN LANE_DEPTH=1 THEN ROW_NUMBER() OVER (" + + "PARTITION BY WAREHOUSE_ID ORDER BY CASE WHEN LANE_DEPTH=1 THEN 0 ELSE 1 END," + + "COLUMN_NO DESC,ROW_NO ASC,FLOOR_NO ASC,STABLE_ID ASC) END AS SINGLE_DEPTH_RANK " + + "FROM LANE_TOPOLOGY), EXPECTED AS (SELECT C.CARGO_SPACE_ID AS SPACE_ID,C.WAREHOUSE_ID," + + "C.GROUP_CODING_NO AS LANE_CODE,R.LANE_DEPTH,CASE WHEN R.LANE_DEPTH=1 " + + "AND R.SINGLE_DEPTH_RANK<=80 THEN 'CACHE' WHEN R.LANE_DEPTH=1 AND R.SINGLE_DEPTH_RANK<=133 " + + "THEN 'RESERVE' WHEN R.LANE_DEPTH=5 THEN 'MAIN' ELSE 'FLEX' END AS BASE_ZONE " + + "FROM BAS_CARGO_SPACE C JOIN RANKED_LANES R ON R.WAREHOUSE_ID=C.WAREHOUSE_ID " + + "AND R.LANE_CODE=C.GROUP_CODING_NO WHERE C.WAREHOUSE_ID=?) " + + "SELECT COUNT(*) FROM EXPECTED E LEFT JOIN ALG_SPACE_TOPOLOGY T ON T.SPACE_ID=E.SPACE_ID " + + "WHERE T.SPACE_ID IS NULL OR T.WAREHOUSE_ID<>E.WAREHOUSE_ID OR T.LANE_CODE<>E.LANE_CODE " + + "OR T.LANE_DEPTH<>E.LANE_DEPTH OR T.BASE_ZONE<>E.BASE_ZONE"; + Integer mismatched = jdbc.queryForObject(expectedMismatch, Integer.class, warehouseId, warehouseId); + if (mismatched != null && mismatched > 0) { + return true; + } + Integer stale = jdbc.queryForObject("SELECT COUNT(*) FROM ALG_SPACE_TOPOLOGY T LEFT JOIN BAS_CARGO_SPACE C " + + "ON C.CARGO_SPACE_ID=T.SPACE_ID AND C.WAREHOUSE_ID=T.WAREHOUSE_ID " + + "WHERE T.WAREHOUSE_ID=? AND C.CARGO_SPACE_ID IS NULL", + Integer.class, warehouseId); + return stale != null && stale > 0; + } + + void rebuild(String warehouseId) { + jdbc.update("DELETE FROM ALG_SPACE_TOPOLOGY WHERE WAREHOUSE_ID=?", warehouseId); + jdbc.update("INSERT INTO ALG_SPACE_TOPOLOGY (WAREHOUSE_ID,SPACE_ID,LANE_CODE,LANE_DEPTH,BASE_ZONE) " + + "WITH LANE_TOPOLOGY AS (SELECT WAREHOUSE_ID,GROUP_CODING_NO AS LANE_CODE," + + "COUNT(*) AS LANE_DEPTH,MAX(THE_COLUMN) AS COLUMN_NO,MIN(THE_PLATOON) AS ROW_NO," + + "MIN(THE_FLOOR) AS FLOOR_NO,MIN(CARGO_SPACE_ID) AS STABLE_ID FROM BAS_CARGO_SPACE " + + "WHERE WAREHOUSE_ID=? GROUP BY WAREHOUSE_ID,GROUP_CODING_NO), RANKED_LANES AS (" + + "SELECT LANE_TOPOLOGY.*,CASE WHEN LANE_DEPTH=1 THEN ROW_NUMBER() OVER (" + + "PARTITION BY WAREHOUSE_ID ORDER BY CASE WHEN LANE_DEPTH=1 THEN 0 ELSE 1 END," + + "COLUMN_NO DESC,ROW_NO ASC,FLOOR_NO ASC,STABLE_ID ASC) END AS SINGLE_DEPTH_RANK " + + "FROM LANE_TOPOLOGY) SELECT C.WAREHOUSE_ID,C.CARGO_SPACE_ID,C.GROUP_CODING_NO," + + "R.LANE_DEPTH,CASE WHEN R.LANE_DEPTH=1 AND R.SINGLE_DEPTH_RANK<=80 THEN 'CACHE' " + + "WHEN R.LANE_DEPTH=1 AND R.SINGLE_DEPTH_RANK<=133 THEN 'RESERVE' " + + "WHEN R.LANE_DEPTH=5 THEN 'MAIN' ELSE 'FLEX' END FROM BAS_CARGO_SPACE C " + + "JOIN RANKED_LANES R ON R.WAREHOUSE_ID=C.WAREHOUSE_ID " + + "AND R.LANE_CODE=C.GROUP_CODING_NO WHERE C.WAREHOUSE_ID=?", + warehouseId, warehouseId); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/InboundReservation.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/InboundReservation.java new file mode 100644 index 0000000..5df00ee --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/InboundReservation.java @@ -0,0 +1,5 @@ +package com.ruoyi.algorithm.repository; + +public record InboundReservation(String reservationId, String warehouseId, String laneCode, + String spaceId, String projectNo, VersionToken expectedVersion) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/InventoryItem.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/InventoryItem.java new file mode 100644 index 0000000..f611481 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/InventoryItem.java @@ -0,0 +1,9 @@ +package com.ruoyi.algorithm.repository; + +import java.math.BigDecimal; +import java.time.Instant; + +public record InventoryItem(String stockId, String spaceId, String trayNo, String projectNo, String productNo, + String lotNo, String inboundTimeRaw, Instant inboundAt, + BigDecimal quantity, BigDecimal outboundQuantity) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepository.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepository.java new file mode 100644 index 0000000..437a558 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepository.java @@ -0,0 +1,845 @@ +package com.ruoyi.algorithm.repository; + +import com.ruoyi.algorithm.inbound.InboundPolicy; +import com.ruoyi.algorithm.model.SpaceRole; +import com.ruoyi.algorithm.model.SpaceState; +import com.ruoyi.algorithm.model.SpaceStatus; +import com.ruoyi.algorithm.policy.SchedulingPolicy; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.support.TransactionTemplate; + +import javax.sql.DataSource; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.sql.Timestamp; +import java.time.Instant; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.EnumSet; +import java.util.HexFormat; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; + +public final class JdbcWarehouseRepository implements WarehouseRepository { + public static final int MAX_PAGE_SIZE = 200; + + private final RepositoryDialect dialect; + private final JdbcTemplate jdbc; + private final NamedParameterJdbcTemplate named; + private final TransactionTemplate transactions; + private final H2TopologyReadModel h2Topology; + private final boolean writesEnabled; + + public JdbcWarehouseRepository(DataSource dataSource, RepositoryDialect dialect) { + this(dataSource, dialect, true); + } + + public JdbcWarehouseRepository(DataSource dataSource, RepositoryDialect dialect, boolean writesEnabled) { + this(dataSource, dialect, writesEnabled, new DataSourceTransactionManager(dataSource)); + } + + public JdbcWarehouseRepository(DataSource dataSource, RepositoryDialect dialect, boolean writesEnabled, + PlatformTransactionManager transactionManager) { + this.dialect = Objects.requireNonNull(dialect, "dialect"); + this.jdbc = new JdbcTemplate(dataSource); + this.named = new NamedParameterJdbcTemplate(dataSource); + this.transactions = new TransactionTemplate(Objects.requireNonNull(transactionManager, "transactionManager")); + this.h2Topology = new H2TopologyReadModel(jdbc); + this.writesEnabled = writesEnabled; + } + + @Override + public void synchronizeReadModel(String warehouseId) { + if (!writesEnabled) throw new IllegalStateException("Database writes are disabled"); + if (blankToNull(warehouseId) == null) throw new IllegalArgumentException("warehouseId is required"); + if (!dialect.h2Database()) { + jdbc.update("EXEC alg.usp_sync_inventory_snapshot @warehouse_id=?", warehouseId); + jdbc.update("EXEC alg.usp_rebuild_lane_state @warehouse_id=?", warehouseId); + return; + } + transactions.executeWithoutResult(status -> synchronizeH2ReadModel(warehouseId)); + } + + @Override + public void refreshChangedLanes(String warehouseId) { + if (!writesEnabled) throw new IllegalStateException("Database writes are disabled"); + if (blankToNull(warehouseId) == null) throw new IllegalArgumentException("warehouseId is required"); + if (!dialect.h2Database()) { + jdbc.update("EXEC alg.usp_refresh_dirty_lanes @warehouse_id=?", warehouseId); + return; + } + transactions.executeWithoutResult(status -> refreshChangedLanesH2(warehouseId)); + } + + private void refreshChangedLanesH2(String warehouseId) { + LinkedHashSet laneCodes = new LinkedHashSet<>(jdbc.queryForList( + "SELECT GROUP_CODING_NO FROM BAS_CARGO_SPACE WHERE WAREHOUSE_ID=? " + + "UNION SELECT LANE_CODE FROM ALG_LANE_STATE WHERE WAREHOUSE_ID=? ORDER BY 1", + String.class, warehouseId, warehouseId)); + if (h2Topology.changed(warehouseId)) { + h2Topology.rebuild(warehouseId); + laneCodes.addAll(jdbc.queryForList("SELECT DISTINCT GROUP_CODING_NO FROM BAS_CARGO_SPACE " + + "WHERE WAREHOUSE_ID=? ORDER BY GROUP_CODING_NO", String.class, warehouseId)); + jdbc.update("DELETE FROM ALG_INVENTORY_ITEM_SNAPSHOT WHERE WAREHOUSE_ID=? AND SPACE_ID NOT IN " + + "(SELECT CARGO_SPACE_ID FROM BAS_CARGO_SPACE WHERE WAREHOUSE_ID=?)", + warehouseId, warehouseId); + jdbc.update("DELETE FROM ALG_SPACE_INVENTORY_SUMMARY WHERE WAREHOUSE_ID=? AND SPACE_ID NOT IN " + + "(SELECT CARGO_SPACE_ID FROM BAS_CARGO_SPACE WHERE WAREHOUSE_ID=?)", + warehouseId, warehouseId); + } + List dirtyLanes = laneCodes.stream().filter(laneCode -> { + List stored = jdbc.queryForList("SELECT SEMANTIC_FINGERPRINT FROM ALG_LANE_STATE " + + "WHERE WAREHOUSE_ID=? AND LANE_CODE=?", + String.class, warehouseId, laneCode); + return stored.isEmpty() || !Objects.equals(stored.get(0), + h2SemanticFingerprint(warehouseId, laneCode, InventoryFingerprintSource.LIVE)); + }).toList(); + dirtyLanes.forEach(laneCode -> refreshH2InventoryLane(warehouseId, laneCode)); + dirtyLanes.forEach(laneCode -> refreshH2LaneState(warehouseId, laneCode)); + } + + private void refreshH2InventoryLane(String warehouseId, String laneCode) { + jdbc.update("DELETE FROM ALG_SPACE_INVENTORY_SUMMARY WHERE WAREHOUSE_ID=? AND SPACE_ID IN " + + "(SELECT CARGO_SPACE_ID FROM BAS_CARGO_SPACE WHERE WAREHOUSE_ID=? AND GROUP_CODING_NO=?)", + warehouseId, warehouseId, laneCode); + jdbc.update("DELETE FROM ALG_INVENTORY_ITEM_SNAPSHOT WHERE WAREHOUSE_ID=? AND SPACE_ID IN " + + "(SELECT CARGO_SPACE_ID FROM BAS_CARGO_SPACE WHERE WAREHOUSE_ID=? AND GROUP_CODING_NO=?)", + warehouseId, warehouseId, laneCode); + jdbc.update("INSERT INTO ALG_INVENTORY_ITEM_SNAPSHOT " + + "(WAREHOUSE_ID,STOCK_ID,SPACE_ID,TRAY_CODE,PROJECT_NO,PRODUCT_NO,LOT_NO," + + "INBOUND_TIME_RAW,INBOUND_AT,QUANTITY,OUT_QUANTITY) " + + "SELECT C.WAREHOUSE_ID,S.STOCK_ID,S.CARGO_SPACE_ID,S.TRAY_CODE,S.SPARE4,S.PRODUCT_ID," + + "S.LOT_NO,S.IN_DATE,ALG_TRY_TIMESTAMP(S.IN_DATE),S.QUANTITY,S.OUT_QUANTITY " + + "FROM BAS_STOCK S JOIN BAS_CARGO_SPACE C ON C.CARGO_SPACE_ID=S.CARGO_SPACE_ID " + + "WHERE C.WAREHOUSE_ID=? AND C.GROUP_CODING_NO=?", + warehouseId, laneCode); + jdbc.update("INSERT INTO ALG_SPACE_INVENTORY_SUMMARY " + + "(WAREHOUSE_ID,SPACE_ID,STOCK_DETAIL_COUNT,STOCK_TRAY_COUNT,STOCK_PROJECT_COUNT,STOCK_PRODUCT_COUNT) " + + "SELECT I.WAREHOUSE_ID,I.SPACE_ID,COUNT(*),COUNT(DISTINCT NULLIF(TRIM(I.TRAY_CODE),''))," + + "COUNT(DISTINCT NULLIF(TRIM(I.PROJECT_NO),'')),COUNT(DISTINCT NULLIF(TRIM(I.PRODUCT_NO),'')) " + + "FROM ALG_INVENTORY_ITEM_SNAPSHOT I JOIN BAS_CARGO_SPACE C ON C.CARGO_SPACE_ID=I.SPACE_ID " + + "AND C.WAREHOUSE_ID=I.WAREHOUSE_ID WHERE I.WAREHOUSE_ID=? AND C.GROUP_CODING_NO=? " + + "GROUP BY I.WAREHOUSE_ID,I.SPACE_ID", + warehouseId, laneCode); + } + + private void refreshH2LaneState(String warehouseId, String laneCode) { + List> source = jdbc.queryForList("SELECT WAREHOUSE_ID,LANE_CODE,COUNT(*) SPACE_COUNT," + + "SUM(CASE WHEN SPACE_STATUS='2' OR STOCK_DETAIL_COUNT>0 THEN 1 ELSE 0 END) OCCUPIED_COUNT," + + "SUM(CASE WHEN INBOUND_AVAILABLE=TRUE THEN 1 ELSE 0 END) AVAILABLE_COUNT," + + "MAX(CASE WHEN PENDING_OUTBOUND=TRUE THEN 1 ELSE 0 END) PENDING_OUTBOUND," + + "MAX(CASE WHEN HAS_GAP=TRUE THEN 1 ELSE 0 END) HAS_GAP " + + "FROM ALG_V_SPACE_STATE WHERE WAREHOUSE_ID=? AND LANE_CODE=? " + + "GROUP BY WAREHOUSE_ID,LANE_CODE", + warehouseId, laneCode); + if (source.isEmpty()) { + jdbc.update("DELETE FROM ALG_LANE_STATE WHERE WAREHOUSE_ID=? AND LANE_CODE=?", + warehouseId, laneCode); + return; + } + Map lane = source.get(0); + int spaces = number(lane, "SPACE_COUNT"); + int occupied = number(lane, "OCCUPIED_COUNT"); + int available = number(lane, "AVAILABLE_COUNT"); + boolean pending = number(lane, "PENDING_OUTBOUND") != 0; + boolean gap = number(lane, "HAS_GAP") != 0; + String fingerprint = h2SemanticFingerprint(warehouseId, laneCode, + InventoryFingerprintSource.SNAPSHOT); + List> existing = jdbc.queryForList( + "SELECT SPACE_COUNT,OCCUPIED_COUNT,AVAILABLE_COUNT,PENDING_OUTBOUND,HAS_GAP," + + "SEMANTIC_FINGERPRINT FROM ALG_LANE_STATE WHERE WAREHOUSE_ID=? AND LANE_CODE=?", + warehouseId, laneCode); + if (existing.isEmpty()) { + jdbc.update("INSERT INTO ALG_LANE_STATE (WAREHOUSE_ID,LANE_CODE,SPACE_COUNT,OCCUPIED_COUNT," + + "AVAILABLE_COUNT,PENDING_OUTBOUND,HAS_GAP,SEMANTIC_FINGERPRINT,STATE_VERSION) " + + "VALUES (?,?,?,?,?,?,?,?,1)", + warehouseId, laneCode, spaces, occupied, available, pending, gap, fingerprint); + return; + } + Map old = existing.get(0); + boolean changed = number(old, "SPACE_COUNT") != spaces || number(old, "OCCUPIED_COUNT") != occupied + || number(old, "AVAILABLE_COUNT") != available + || booleanValue(old.get("PENDING_OUTBOUND")) != pending + || booleanValue(old.get("HAS_GAP")) != gap + || !Objects.equals(old.get("SEMANTIC_FINGERPRINT"), fingerprint); + if (changed) { + jdbc.update("UPDATE ALG_LANE_STATE SET SPACE_COUNT=?,OCCUPIED_COUNT=?,AVAILABLE_COUNT=?," + + "PENDING_OUTBOUND=?,HAS_GAP=?,SEMANTIC_FINGERPRINT=?,STATE_VERSION=STATE_VERSION+1," + + "REBUILT_AT=CURRENT_TIMESTAMP WHERE WAREHOUSE_ID=? AND LANE_CODE=?", + spaces, occupied, available, pending, gap, fingerprint, warehouseId, laneCode); + } + } + + private void synchronizeH2ReadModel(String warehouseId) { + jdbc.update("DELETE FROM ALG_SPACE_INVENTORY_SUMMARY WHERE WAREHOUSE_ID = ?", warehouseId); + jdbc.update("DELETE FROM ALG_INVENTORY_ITEM_SNAPSHOT WHERE WAREHOUSE_ID = ?", warehouseId); + jdbc.update("INSERT INTO ALG_INVENTORY_ITEM_SNAPSHOT " + + "(WAREHOUSE_ID,STOCK_ID,SPACE_ID,TRAY_CODE,PROJECT_NO,PRODUCT_NO,LOT_NO," + + "INBOUND_TIME_RAW,INBOUND_AT,QUANTITY,OUT_QUANTITY) " + + "SELECT C.WAREHOUSE_ID,S.STOCK_ID,S.CARGO_SPACE_ID,S.TRAY_CODE,S.SPARE4,S.PRODUCT_ID," + + "S.LOT_NO,S.IN_DATE,ALG_TRY_TIMESTAMP(S.IN_DATE),S.QUANTITY,S.OUT_QUANTITY " + + "FROM BAS_STOCK S JOIN BAS_CARGO_SPACE C ON C.CARGO_SPACE_ID=S.CARGO_SPACE_ID " + + "WHERE C.WAREHOUSE_ID = ?", warehouseId); + jdbc.update("INSERT INTO ALG_SPACE_INVENTORY_SUMMARY " + + "(WAREHOUSE_ID,SPACE_ID,STOCK_DETAIL_COUNT,STOCK_TRAY_COUNT,STOCK_PROJECT_COUNT,STOCK_PRODUCT_COUNT) " + + "SELECT WAREHOUSE_ID,SPACE_ID,COUNT(*),COUNT(DISTINCT NULLIF(TRIM(TRAY_CODE),''))," + + "COUNT(DISTINCT NULLIF(TRIM(PROJECT_NO),'')),COUNT(DISTINCT NULLIF(TRIM(PRODUCT_NO),'')) " + + "FROM ALG_INVENTORY_ITEM_SNAPSHOT WHERE WAREHOUSE_ID = ? GROUP BY WAREHOUSE_ID,SPACE_ID", + warehouseId); + + List> source = jdbc.queryForList("SELECT WAREHOUSE_ID,LANE_CODE,COUNT(*) SPACE_COUNT," + + "SUM(CASE WHEN SPACE_STATUS='2' OR STOCK_DETAIL_COUNT>0 THEN 1 ELSE 0 END) OCCUPIED_COUNT," + + "SUM(CASE WHEN INBOUND_AVAILABLE=TRUE THEN 1 ELSE 0 END) AVAILABLE_COUNT," + + "MAX(CASE WHEN PENDING_OUTBOUND=TRUE THEN 1 ELSE 0 END) PENDING_OUTBOUND," + + "MAX(CASE WHEN HAS_GAP=TRUE THEN 1 ELSE 0 END) HAS_GAP " + + "FROM ALG_V_SPACE_STATE WHERE WAREHOUSE_ID=? GROUP BY WAREHOUSE_ID,LANE_CODE ORDER BY LANE_CODE", + warehouseId); + Set currentLanes = new LinkedHashSet<>(); + for (Map lane : source) { + String laneCode = lane.get("LANE_CODE").toString(); + currentLanes.add(laneCode); + String fingerprint = h2SemanticFingerprint(warehouseId, laneCode, + InventoryFingerprintSource.SNAPSHOT); + List> existing = jdbc.queryForList("SELECT SPACE_COUNT,OCCUPIED_COUNT,AVAILABLE_COUNT," + + "PENDING_OUTBOUND,HAS_GAP,SEMANTIC_FINGERPRINT,STATE_VERSION FROM ALG_LANE_STATE " + + "WHERE WAREHOUSE_ID=? AND LANE_CODE=?", warehouseId, laneCode); + int spaces = number(lane, "SPACE_COUNT"); + int occupied = number(lane, "OCCUPIED_COUNT"); + int available = number(lane, "AVAILABLE_COUNT"); + boolean pending = number(lane, "PENDING_OUTBOUND") != 0; + boolean gap = number(lane, "HAS_GAP") != 0; + if (existing.isEmpty()) { + jdbc.update("INSERT INTO ALG_LANE_STATE (WAREHOUSE_ID,LANE_CODE,SPACE_COUNT,OCCUPIED_COUNT," + + "AVAILABLE_COUNT,PENDING_OUTBOUND,HAS_GAP,SEMANTIC_FINGERPRINT,STATE_VERSION) " + + "VALUES (?,?,?,?,?,?,?,?,1)", warehouseId, laneCode, spaces, occupied, available, + pending, gap, fingerprint); + continue; + } + Map old = existing.get(0); + boolean changed = number(old, "SPACE_COUNT") != spaces || number(old, "OCCUPIED_COUNT") != occupied + || number(old, "AVAILABLE_COUNT") != available + || booleanValue(old.get("PENDING_OUTBOUND")) != pending + || booleanValue(old.get("HAS_GAP")) != gap + || !fingerprint.equals(Objects.toString(old.get("SEMANTIC_FINGERPRINT"), "")); + if (changed) { + jdbc.update("UPDATE ALG_LANE_STATE SET SPACE_COUNT=?,OCCUPIED_COUNT=?,AVAILABLE_COUNT=?," + + "PENDING_OUTBOUND=?,HAS_GAP=?,SEMANTIC_FINGERPRINT=?,STATE_VERSION=STATE_VERSION+1," + + "REBUILT_AT=CURRENT_TIMESTAMP WHERE WAREHOUSE_ID=? AND LANE_CODE=?", + spaces, occupied, available, pending, gap, fingerprint, warehouseId, laneCode); + } + } + jdbc.queryForList("SELECT LANE_CODE FROM ALG_LANE_STATE WHERE WAREHOUSE_ID=?", String.class, warehouseId) + .stream().filter(lane -> !currentLanes.contains(lane)) + .forEach(lane -> jdbc.update("DELETE FROM ALG_LANE_STATE WHERE WAREHOUSE_ID=? AND LANE_CODE=?", + warehouseId, lane)); + } + + private String h2SemanticFingerprint(String warehouseId, String laneCode, + InventoryFingerprintSource inventorySource) { + StringBuilder payload = new StringBuilder(); + appendRows(payload, "SELECT C.CARGO_SPACE_ID,C.STATUS,C.LOCKED,C.TRAY_CODE,C.GROUP_CODING," + + "C.THE_PLATOON,C.THE_COLUMN,C.THE_FLOOR,T.LANE_DEPTH,T.BASE_ZONE,COALESCE(R.ROLE,'STORAGE') " + + "FROM BAS_CARGO_SPACE C LEFT JOIN ALG_SPACE_TOPOLOGY T ON T.SPACE_ID=C.CARGO_SPACE_ID " + + "LEFT JOIN ALG_SPACE_ROLE R ON R.SPACE_ID=C.CARGO_SPACE_ID " + + "WHERE C.WAREHOUSE_ID=? AND C.GROUP_CODING_NO=? " + + "ORDER BY CASE WHEN C.GROUP_CODING REGEXP '^[0-9]+$' THEN CAST(C.GROUP_CODING AS INT) END,C.CARGO_SPACE_ID", + warehouseId, laneCode); + String inventorySql = inventorySource == InventoryFingerprintSource.SNAPSHOT + ? "SELECT S.STOCK_ID,S.SPACE_ID,S.TRAY_CODE,S.PROJECT_NO,S.PRODUCT_NO,S.LOT_NO," + + "S.INBOUND_TIME_RAW,CAST(S.QUANTITY AS DECIMAL(38,6)),CAST(S.OUT_QUANTITY AS DECIMAL(38,6)) " + + "FROM ALG_INVENTORY_ITEM_SNAPSHOT S JOIN BAS_CARGO_SPACE C " + + "ON C.CARGO_SPACE_ID=S.SPACE_ID AND C.WAREHOUSE_ID=S.WAREHOUSE_ID " + + "WHERE C.WAREHOUSE_ID=? AND C.GROUP_CODING_NO=? ORDER BY S.SPACE_ID,S.STOCK_ID" + : "SELECT S.STOCK_ID,S.CARGO_SPACE_ID,S.TRAY_CODE,S.SPARE4,S.PRODUCT_ID,S.LOT_NO," + + "S.IN_DATE,CAST(S.QUANTITY AS DECIMAL(38,6)),CAST(S.OUT_QUANTITY AS DECIMAL(38,6)) " + + "FROM BAS_STOCK S JOIN BAS_CARGO_SPACE C ON C.CARGO_SPACE_ID=S.CARGO_SPACE_ID " + + "WHERE C.WAREHOUSE_ID=? AND C.GROUP_CODING_NO=? ORDER BY S.CARGO_SPACE_ID,S.STOCK_ID"; + appendRows(payload, inventorySql, warehouseId, laneCode); + appendRows(payload, "SELECT JOB_ID,TASK_NO,TRAY_CODE,SOURCE_SPACE_ID,TARGET_CARGO_SPACE_ID,STATUS,IN_OR_OUT,CREATE_TIME_RAW " + + "FROM ALG_V_ACTIVE_JOB WHERE WAREHOUSE_ID=? AND SOURCE_LANE_CODE=? ORDER BY JOB_ID", + warehouseId, laneCode); + appendRows(payload, "SELECT PROJECT_NO,IS_ISOLATED,IS_COMMON,ALLOW_MIXED FROM ALG_PROJECT_POLICY ORDER BY PROJECT_NO"); + appendRows(payload, "SELECT WAREHOUSE_ID,TARGET_FILL_RATE,FIFO_TOLERANCE_HOURS FROM ALG_WAREHOUSE_POLICY WHERE WAREHOUSE_ID=?", + warehouseId); + appendRows(payload, "SELECT RESERVATION_ID,SPACE_ID,PROJECT_NO,STATUS FROM ALG_RESERVATION " + + "WHERE WAREHOUSE_ID=? AND LANE_CODE=? AND STATUS='ACTIVE' ORDER BY SPACE_ID,RESERVATION_ID", + warehouseId, laneCode); + try { + return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256") + .digest(payload.toString().getBytes(StandardCharsets.UTF_8))); + } catch (NoSuchAlgorithmException exception) { + throw new IllegalStateException("SHA-256 is unavailable", exception); + } + } + + private void appendRows(StringBuilder payload, String sql, Object... arguments) { + payload.append('|'); + jdbc.query(sql, rs -> { + int columns = rs.getMetaData().getColumnCount(); + payload.append('['); + for (int index = 1; index <= columns; index++) { + String value = rs.getString(index); + payload.append(value == null ? -1 : value.length()).append(':'); + if (value != null) payload.append(value); + payload.append(';'); + } + payload.append(']'); + }, arguments); + } + + private int number(Map row, String column) { + Object value = row.get(column); + return value == null ? 0 : ((Number) value).intValue(); + } + + private boolean booleanValue(Object value) { + return value instanceof Boolean bool ? bool : value instanceof Number number && number.intValue() != 0; + } + + @Override + public WarehouseSummary loadSummary(String warehouseId) { + String sql = "SELECT COUNT(DISTINCT lane_code) AS lane_count, COUNT(*) AS space_count, " + + "SUM(CASE WHEN space_status = '2' OR stock_detail_count > 0 THEN 1 ELSE 0 END) AS occupied_count, " + + "SUM(CASE WHEN inbound_available = " + dialect.trueLiteral() + " THEN 1 ELSE 0 END) AS available_count, " + + "COUNT(DISTINCT CASE WHEN pending_outbound = " + dialect.trueLiteral() + " THEN lane_code END) AS pending_lane_count, " + + "SUM(CASE WHEN tray_conflict = " + dialect.trueLiteral() + " OR project_conflict = " + dialect.trueLiteral() + + " OR product_conflict = " + dialect.trueLiteral() + " THEN 1 ELSE 0 END) AS conflict_count, " + + "SUM(CASE WHEN reserved = " + dialect.trueLiteral() + " THEN 1 ELSE 0 END) AS reserved_count " + + "FROM " + dialect.spaceStateView() + " WHERE warehouse_id = ?"; + return jdbc.queryForObject(sql, (rs, row) -> new WarehouseSummary(warehouseId, + rs.getInt("lane_count"), rs.getInt("space_count"), rs.getInt("occupied_count"), + rs.getInt("available_count"), rs.getInt("pending_lane_count"), rs.getInt("conflict_count"), + rs.getInt("reserved_count")), warehouseId); + } + + @Override + public LanePage pageCandidateLanes(String warehouseId, String afterLaneCode, int pageSize) { + return pageLanes(warehouseId, afterLaneCode, pageSize, + " AND available_count > 0 AND pending_outbound = " + dialect.falseLiteral() + + " AND has_gap = " + dialect.falseLiteral()); + } + + @Override + public LanePage pageWarehouseLanes(String warehouseId, String afterLaneCode, int pageSize) { + return pageLanes(warehouseId, afterLaneCode, pageSize, ""); + } + + private LanePage pageLanes(String warehouseId, String afterLaneCode, int requestedSize, String hardFacts) { + int size = Math.max(1, Math.min(MAX_PAGE_SIZE, requestedSize)); + String projection = "warehouse_id, lane_code, space_count, occupied_count, available_count, " + + "pending_outbound, has_gap, state_version"; + String sql = "SELECT TOP (:limit) " + projection + " FROM " + dialect.laneState() + + " WHERE warehouse_id = :warehouse AND lane_code > :after" + hardFacts + + " ORDER BY lane_code"; + List lanes = named.query(sql, new MapSqlParameterSource() + .addValue("warehouse", warehouseId).addValue("after", blankToEmpty(afterLaneCode)) + .addValue("limit", size), laneCandidateMapper()); + String next = lanes.size() == size ? lanes.get(lanes.size() - 1).laneCode() : null; + return new LanePage(lanes, next); + } + + @Override + public List loadLaneSnapshots(String warehouseId, Collection laneCodes) { + LinkedHashSet codes = laneCodes == null ? new LinkedHashSet<>() + : laneCodes.stream().filter(Objects::nonNull).collect(Collectors.toCollection(LinkedHashSet::new)); + if (codes.isEmpty()) return List.of(); + MapSqlParameterSource parameters = new MapSqlParameterSource() + .addValue("warehouse", warehouseId).addValue("lanes", codes); + Map versions = new LinkedHashMap<>(); + named.query("SELECT lane_code, state_version FROM " + dialect.laneState() + + " WHERE warehouse_id = :warehouse AND lane_code IN (:lanes)", parameters, + (rs, row) -> Map.entry(rs.getString("lane_code"), + VersionToken.fromJdbc(rs.getObject("state_version")))) + .forEach(entry -> versions.put(entry.getKey(), entry.getValue())); + + List rawSpaces = named.query("SELECT space_id, warehouse_id, lane_code, area_id, zone_code, roadway_id, " + + "platoon, column_no, floor_no, depth, space_status, locked, space_tray_code, role, " + + "tray_conflict, project_conflict, product_conflict, pending_outbound, reserved, has_gap, inbound_available " + + "FROM " + dialect.spaceStateView() + + " WHERE warehouse_id = :warehouse AND lane_code IN (:lanes) " + + "ORDER BY lane_code, depth, space_id", parameters, rawSpaceMapper()); + List inventory = named.query("SELECT i.stock_id, i.space_id, i.tray_code, i.project_no, " + + "i.product_no, i.lot_no, i.inbound_time_raw, i.inbound_at, i.quantity, i.out_quantity " + + "FROM " + dialect.inventoryView() + " i JOIN " + dialect.spaceStateView() + " s ON s.space_id = i.space_id " + + "WHERE s.warehouse_id = :warehouse AND s.lane_code IN (:lanes) " + + "ORDER BY i.space_id, i.stock_id", parameters, inventoryMapper()); + Map> inventoryBySpace = inventory.stream() + .collect(Collectors.groupingBy(InventoryItem::spaceId, LinkedHashMap::new, Collectors.toList())); + Map> byLane = rawSpaces.stream() + .collect(Collectors.groupingBy(RawSpace::laneCode, LinkedHashMap::new, Collectors.toList())); + List result = new ArrayList<>(); + byLane.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(entry -> { + int capacity = entry.getValue().size(); + List spaces = entry.getValue().stream() + .map(raw -> mapSpace(raw, capacity, versions.get(entry.getKey()), + inventoryBySpace.getOrDefault(raw.spaceId(), List.of()))) + .sorted(Comparator.comparingInt((SpaceSnapshot value) -> value.state().depthOrder()) + .thenComparing(SpaceSnapshot::spaceId)).toList(); + result.add(new LaneSnapshot(warehouseId, entry.getKey(), versions.get(entry.getKey()), spaces)); + }); + return List.copyOf(result); + } + + @Override + public List loadRelocationBuffers(String warehouseId, Set floors) { + if (floors == null || floors.isEmpty()) return List.of(); + List laneCodes = named.queryForList("SELECT DISTINCT lane_code FROM " + dialect.spaceStateView() + + " WHERE warehouse_id = :warehouse AND role = 'RELOCATION_BUFFER' AND floor_no IN (:floors) " + + "ORDER BY lane_code", new MapSqlParameterSource().addValue("warehouse", warehouseId) + .addValue("floors", floors), String.class); + return loadLaneSnapshots(warehouseId, laneCodes).stream().flatMap(lane -> lane.spaces().stream()) + .filter(space -> space.state().role() == SpaceRole.RELOCATION_BUFFER) + .filter(space -> floors.contains(space.state().floorNo())).toList(); + } + + @Override + public Set loadActiveDeepWorkflowFloors(String warehouseId, String excludingRequestId) { + String sql = "SELECT floor_no FROM " + dialect.deepWorkflowLock() + + " WHERE warehouse_id = ? AND status = 'ACTIVE' AND (? IS NULL OR request_id <> ?) ORDER BY floor_no"; + String excluded = blankToNull(excludingRequestId); + return new LinkedHashSet<>(jdbc.queryForList(sql, Integer.class, warehouseId, excluded, excluded)); + } + + @Override + public boolean acquireDeepWorkflowLock(String requestId, String warehouseId, int floorNo) { + return acquireDeepWorkflowLockResult(requestId, warehouseId, floorNo).changed(); + } + + @Override + public DeepWorkflowMutationResult acquireDeepWorkflowLockResult(String requestId, String warehouseId, int floorNo) { + if (!writesEnabled) return DeepWorkflowMutationResult.writesDisabled(); + validateWorkflowLock(requestId, warehouseId, floorNo); + boolean acquired = dialect.h2Database() ? acquireDeepWorkflowH2(requestId, warehouseId, floorNo) + : named.queryForObject("EXEC " + dialect.acquireDeepWorkflowProcedure() + + " @request_id=:request, @warehouse_id=:warehouse, @floor_no=:floor", + new MapSqlParameterSource().addValue("request", requestId).addValue("warehouse", warehouseId) + .addValue("floor", floorNo), (rs, row) -> rs.getBoolean("acquired")); + return acquired ? DeepWorkflowMutationResult.succeeded() : DeepWorkflowMutationResult.unchanged(); + } + + @Override + public boolean releaseDeepWorkflowLock(String requestId, String warehouseId, int floorNo) { + return releaseDeepWorkflowLockResult(requestId, warehouseId, floorNo).changed(); + } + + @Override + public DeepWorkflowMutationResult releaseDeepWorkflowLockResult(String requestId, String warehouseId, int floorNo) { + if (!writesEnabled) return DeepWorkflowMutationResult.writesDisabled(); + validateWorkflowLock(requestId, warehouseId, floorNo); + boolean released = dialect.h2Database() ? releaseDeepWorkflowH2(requestId, warehouseId, floorNo) + : named.queryForObject("EXEC " + dialect.releaseDeepWorkflowProcedure() + + " @request_id=:request, @warehouse_id=:warehouse, @floor_no=:floor", + new MapSqlParameterSource().addValue("request", requestId).addValue("warehouse", warehouseId) + .addValue("floor", floorNo), (rs, row) -> rs.getBoolean("released")); + return released ? DeepWorkflowMutationResult.succeeded() : DeepWorkflowMutationResult.unchanged(); + } + + @Override + public List loadPendingOutboundJobs(String warehouseId) { + String sql = "SELECT job_id, task_no, tray_code, project_no, product_no, source_space_id, warehouse_id, source_lane_code, " + + "source_resolution, status, in_or_out, create_time_raw FROM " + dialect.activeJobView() + + " WHERE warehouse_id = ? AND in_or_out >= 20 ORDER BY job_id"; + return jdbc.query(sql, (rs, row) -> new PendingOutboundJob(rs.getString("job_id"), rs.getString("task_no"), + rs.getString("tray_code"), rs.getString("project_no"), rs.getString("product_no"), + rs.getString("source_space_id"), rs.getString("warehouse_id"), rs.getString("source_lane_code"), + rs.getString("source_resolution"), rs.getString("status"), rs.getInt("in_or_out"), + rs.getString("create_time_raw")), warehouseId); + } + + @Override + public List searchOutboundStock(String warehouseId, OutboundStockSearch search) { + String predicate = search.trayNo() != null ? "i.tray_code = :tray" + : "i.project_no = :project AND (:product IS NULL OR i.product_no = :product)"; + MapSqlParameterSource parameters = new MapSqlParameterSource().addValue("warehouse", warehouseId) + .addValue("tray", search.trayNo()).addValue("project", search.projectNo()) + .addValue("product", blankToNull(search.productNo())); + String sql = "SELECT i.stock_id, i.space_id, s.lane_code, s.floor_no, i.tray_code, i.project_no, " + + "i.product_no, i.lot_no, i.inbound_time_raw, i.inbound_at FROM " + dialect.inventoryView() + + " i JOIN " + dialect.spaceStateView() + " s ON s.space_id = i.space_id " + + "WHERE s.warehouse_id = :warehouse AND " + predicate + + " ORDER BY i.inbound_at, i.inbound_time_raw, i.stock_id"; + List matches = named.query(sql, parameters, (rs, row) -> new OutboundStockMatch( + rs.getString("stock_id"), rs.getString("space_id"), rs.getString("lane_code"), + rs.getInt("floor_no"), rs.getString("tray_code"), rs.getString("project_no"), + rs.getString("product_no"), rs.getString("lot_no"), rs.getString("inbound_time_raw"), + instant(rs, "inbound_at"))); + if (search.trayNo() == null) return matches; + + List cargoMatches = named.query("SELECT space_id, lane_code, floor_no, space_tray_code FROM " + + dialect.spaceStateView() + " WHERE warehouse_id = :warehouse " + + "AND LTRIM(RTRIM(space_tray_code)) = :tray ORDER BY space_id", + parameters, (rs, row) -> new OutboundStockMatch("CARGO_SPACE:" + rs.getString("space_id"), + rs.getString("space_id"), rs.getString("lane_code"), rs.getInt("floor_no"), + rs.getString("space_tray_code"), null, null, null, null, null)); + Set matchedSpaces = matches.stream().map(OutboundStockMatch::spaceId) + .collect(Collectors.toCollection(LinkedHashSet::new)); + List combined = new ArrayList<>(matches); + cargoMatches.stream().filter(match -> matchedSpaces.add(match.spaceId())).forEach(combined::add); + return List.copyOf(combined); + } + + @Override + public int countProjectPallets(String warehouseId, String projectNo) { + String usableTray = "CASE WHEN s.stock_tray_count = 1 THEN NULLIF(LTRIM(RTRIM(i.tray_code)), '') " + + "WHEN s.stock_tray_count = 0 THEN NULLIF(LTRIM(RTRIM(s.space_tray_code)), '') END"; + Integer count = named.queryForObject("SELECT COUNT(DISTINCT " + usableTray + ") FROM " + + dialect.spaceStateView() + " s JOIN " + dialect.inventoryView() + + " i ON i.space_id = s.space_id WHERE s.warehouse_id = :warehouse " + + "AND NULLIF(LTRIM(RTRIM(i.project_no)), '') = :project AND s.space_status = '2' " + + "AND s.role = 'STORAGE' AND s.depth IS NOT NULL AND s.pending_outbound = " + + dialect.falseLiteral() + " AND s.reserved = " + dialect.falseLiteral() + + " AND s.has_gap = " + dialect.falseLiteral() + " AND s.tray_conflict = " + + dialect.falseLiteral() + " AND s.project_conflict = " + dialect.falseLiteral() + + " AND (NULLIF(LTRIM(RTRIM(s.locked)), '') IS NULL OR LTRIM(RTRIM(s.locked)) IN ('0', 'N')) " + + "AND (NULLIF(LTRIM(RTRIM(s.space_tray_code)), '') IS NULL " + + "OR NULLIF(LTRIM(RTRIM(i.tray_code)), '') IS NULL " + + "OR LTRIM(RTRIM(s.space_tray_code)) = LTRIM(RTRIM(i.tray_code)))", + new MapSqlParameterSource().addValue("warehouse", warehouseId).addValue("project", projectNo), + Integer.class); + return count == null ? 0 : count; + } + + @Override + public RepositoryPolicy loadPolicy(String warehouseId) { + List> warehouses = jdbc.queryForList("SELECT target_fill_rate, fifo_tolerance_hours FROM " + + dialect.warehousePolicy() + " WHERE warehouse_id = ?", warehouseId); + double targetFill = warehouses.isEmpty() || warehouses.get(0).get("TARGET_FILL_RATE") == null ? 0.0 + : ((Number) warehouses.get(0).get("TARGET_FILL_RATE")).doubleValue(); + int toleranceMinutes = warehouses.isEmpty() || warehouses.get(0).get("FIFO_TOLERANCE_HOURS") == null ? 0 + : ((Number) warehouses.get(0).get("FIFO_TOLERANCE_HOURS")).intValue() * 60; + Set isolated = new LinkedHashSet<>(); + Set common = new LinkedHashSet<>(); + Set mixedDenied = new LinkedHashSet<>(); + jdbc.query("SELECT project_no, is_isolated, is_common, allow_mixed FROM " + dialect.projectPolicy(), rs -> { + if (rs.getBoolean("is_isolated")) isolated.add(rs.getString("project_no")); + if (rs.getBoolean("is_common")) common.add(rs.getString("project_no")); + if (!rs.getBoolean("allow_mixed")) mixedDenied.add(rs.getString("project_no")); + }); + if (common.isEmpty()) common.add("COMMON"); + SchedulingPolicy scheduling = SchedulingPolicy.ft546Defaults(); + return new RepositoryPolicy(new InboundPolicy(scheduling, isolated, common, List.of(), 0, mixedDenied), + scheduling, toleranceMinutes, targetFill); + } + + @Override + public DecisionLogEntry insertDecision(DecisionLogRecord record) { + String id = blankToNull(record.decisionId()) == null ? UUID.randomUUID().toString() : record.decisionId(); + if (!writesEnabled) { + return new DecisionLogEntry(id, record.warehouseId(), record.decisionType(), record.inputVersion(), + record.resultCode(), abbreviate(record.reason(), 2000), Instant.now()); + } + named.update("INSERT INTO " + dialect.decisionLog() + + " (decision_id, warehouse_id, decision_type, input_version, result_code, reason) " + + "VALUES (:id, :warehouse, :type, :version, :result, :reason)", + new MapSqlParameterSource().addValue("id", sqlId(id)).addValue("warehouse", record.warehouseId()) + .addValue("type", record.decisionType()).addValue("version", versionValue(record.inputVersion()), + decisionVersionSqlType(dialect)) + .addValue("result", record.resultCode()).addValue("reason", abbreviate(record.reason(), 2000))); + return findDecision(id).orElseThrow(); + } + + @Override + public Optional findDecision(String decisionId) { + List values = jdbc.query("SELECT decision_id, warehouse_id, decision_type, input_version, " + + "result_code, reason, created_at FROM " + dialect.decisionLog() + " WHERE decision_id = ?", + (rs, row) -> new DecisionLogEntry(rs.getString("decision_id"), rs.getString("warehouse_id"), + rs.getString("decision_type"), VersionToken.fromJdbc(rs.getObject("input_version")), + rs.getString("result_code"), rs.getString("reason"), instant(rs, "created_at")), sqlId(decisionId)); + return values.stream().findFirst(); + } + + @Override + public ReservationResult tryReserveInbound(InboundReservation reservation) { + if (!writesEnabled) return ReservationResult.conflict("WRITES_DISABLED", reservation.reservationId()); + sqlId(reservation.reservationId()); + if (reservation.expectedVersion() == null) { + return ReservationResult.conflict("LANE_VERSION_MISMATCH", reservation.reservationId()); + } + return dialect.h2Database() ? reserveH2(reservation) : reserveSqlServer(reservation); + } + + @Override + public ReservationResult releaseReservation(String warehouseId, String reservationId) { + if (!writesEnabled) return ReservationResult.conflict("WRITES_DISABLED", reservationId); + return dialect.h2Database() ? releaseH2(warehouseId, reservationId) : releaseSqlServer(warehouseId, reservationId); + } + + private ReservationResult reserveH2(InboundReservation reservation) { + return transactions.execute(status -> { + List values = jdbc.query("SELECT state_version, semantic_fingerprint FROM " + dialect.laneState() + + " WHERE warehouse_id = ? AND lane_code = ? FOR UPDATE", + (rs, row) -> new LaneReservationState(VersionToken.fromJdbc(rs.getObject("state_version")), + rs.getString("semantic_fingerprint")), + reservation.warehouseId(), reservation.laneCode()); + if (values.isEmpty() || !reservation.expectedVersion().equals(values.get(0).version())) { + return ReservationResult.conflict("LANE_VERSION_MISMATCH", reservation.reservationId()); + } + String storedFingerprint = values.get(0).semanticFingerprint(); + if (storedFingerprint != null && !storedFingerprint.isBlank() + && !storedFingerprint.equals(h2SemanticFingerprint( + reservation.warehouseId(), reservation.laneCode(), InventoryFingerprintSource.LIVE))) { + return ReservationResult.conflict("LANE_VERSION_MISMATCH", reservation.reservationId()); + } + Integer pending = jdbc.queryForObject("SELECT COUNT(*) FROM " + dialect.activeJobView() + + " WHERE warehouse_id = ? AND in_or_out >= 20 AND source_lane_code = ?", + Integer.class, reservation.warehouseId(), reservation.laneCode()); + if (pending != null && pending > 0) { + return ReservationResult.conflict("PENDING_OUTBOUND", reservation.reservationId()); + } + Integer active = jdbc.queryForObject("SELECT COUNT(*) FROM " + dialect.reservation() + + " WHERE space_id = ? AND status = 'ACTIVE'", Integer.class, reservation.spaceId()); + if (active != null && active > 0) { + return ReservationResult.conflict("ACTIVE_RESERVATION_EXISTS", reservation.reservationId()); + } + Integer eligible = jdbc.queryForObject("SELECT COUNT(*) FROM " + dialect.spaceStateView() + + " WHERE warehouse_id = ? AND lane_code = ? AND space_id = ? AND inbound_available = TRUE", + Integer.class, reservation.warehouseId(), reservation.laneCode(), reservation.spaceId()); + if (eligible == null || eligible == 0) { + return ReservationResult.conflict("SPACE_NOT_ELIGIBLE", reservation.reservationId()); + } + try { + jdbc.update("INSERT INTO " + dialect.reservation() + + " (reservation_id, warehouse_id, lane_code, space_id, project_no, status) " + + "VALUES (?, ?, ?, ?, ?, 'ACTIVE')", sqlId(reservation.reservationId()), + reservation.warehouseId(), reservation.laneCode(), reservation.spaceId(), reservation.projectNo()); + } catch (DuplicateKeyException exception) { + return ReservationResult.conflict("ACTIVE_RESERVATION_EXISTS", reservation.reservationId()); + } + rebuildH2Lane(reservation.warehouseId(), reservation.laneCode()); + return ReservationResult.reserved(reservation.reservationId()); + }); + } + + private boolean acquireDeepWorkflowH2(String requestId, String warehouseId, int floorNo) { + return Boolean.TRUE.equals(transactions.execute(status -> { + List owners = jdbc.query("SELECT request_id FROM " + dialect.deepWorkflowLock() + + " WHERE warehouse_id = ? AND floor_no = ? AND status = 'ACTIVE' FOR UPDATE", + (rs, row) -> rs.getString("request_id"), warehouseId, floorNo); + if (!owners.isEmpty()) return requestId.equals(owners.get(0)); + try { + jdbc.update("INSERT INTO " + dialect.deepWorkflowLock() + + " (lock_id, request_id, warehouse_id, floor_no, status) VALUES (?, ?, ?, ?, 'ACTIVE')", + UUID.randomUUID().toString(), requestId, warehouseId, floorNo); + return true; + } catch (DuplicateKeyException exception) { + return false; + } + })); + } + + private boolean releaseDeepWorkflowH2(String requestId, String warehouseId, int floorNo) { + return Boolean.TRUE.equals(transactions.execute(status -> jdbc.update("UPDATE " + dialect.deepWorkflowLock() + + " SET status = 'RELEASED', released_at = CURRENT_TIMESTAMP WHERE request_id = ? " + + "AND warehouse_id = ? AND floor_no = ? AND status = 'ACTIVE'", + requestId, warehouseId, floorNo) == 1)); + } + + private ReservationResult releaseH2(String warehouseId, String reservationId) { + return transactions.execute(status -> { + Object reservationKey = sqlId(reservationId); + List> rows = jdbc.queryForList("SELECT warehouse_id, lane_code FROM " + + dialect.reservation() + " WHERE reservation_id = ? AND warehouse_id = ? AND status = 'ACTIVE' FOR UPDATE", + reservationKey, warehouseId); + if (rows.isEmpty()) return ReservationResult.notFound(reservationId); + jdbc.update("UPDATE " + dialect.reservation() + + " SET status = 'RELEASED', released_at = CURRENT_TIMESTAMP WHERE reservation_id = ? AND warehouse_id = ?", + reservationKey, warehouseId); + String warehouse = Objects.toString(rows.get(0).get("WAREHOUSE_ID"), null); + String lane = Objects.toString(rows.get(0).get("LANE_CODE"), null); + rebuildH2Lane(warehouse, lane); + return ReservationResult.released(reservationId); + }); + } + + private void rebuildH2Lane(String warehouseId, String laneCode) { + String fingerprint = h2SemanticFingerprint(warehouseId, laneCode, + InventoryFingerprintSource.SNAPSHOT); + jdbc.update("UPDATE " + dialect.laneState() + " SET " + + "space_count = (SELECT COUNT(*) FROM " + dialect.spaceStateView() + " WHERE warehouse_id = ? AND lane_code = ?), " + + "occupied_count = (SELECT COUNT(*) FROM " + dialect.spaceStateView() + " WHERE warehouse_id = ? AND lane_code = ? AND (space_status = '2' OR stock_detail_count > 0)), " + + "available_count = (SELECT COUNT(*) FROM " + dialect.spaceStateView() + " WHERE warehouse_id = ? AND lane_code = ? AND inbound_available = TRUE), " + + "pending_outbound = CASE WHEN EXISTS (SELECT 1 FROM " + dialect.spaceStateView() + " WHERE warehouse_id = ? AND lane_code = ? AND pending_outbound = TRUE) THEN TRUE ELSE FALSE END, " + + "has_gap = CASE WHEN EXISTS (SELECT 1 FROM " + dialect.spaceStateView() + " WHERE warehouse_id = ? AND lane_code = ? AND has_gap = TRUE) THEN TRUE ELSE FALSE END, " + + "semantic_fingerprint = ?, state_version = state_version + 1, rebuilt_at = CURRENT_TIMESTAMP " + + "WHERE warehouse_id = ? AND lane_code = ?", + warehouseId, laneCode, warehouseId, laneCode, warehouseId, laneCode, + warehouseId, laneCode, warehouseId, laneCode, fingerprint, warehouseId, laneCode); + } + + private ReservationResult reserveSqlServer(InboundReservation reservation) { + String sql = "EXEC " + dialect.tryReserveProcedure() + + " @warehouse_id=:warehouse, @lane_code=:lane, @space_id=:space, @project_no=:project, " + + "@expected_state_version=:version, @reservation_id=:reservation"; + return named.queryForObject(sql, new MapSqlParameterSource().addValue("warehouse", reservation.warehouseId()) + .addValue("lane", reservation.laneCode()).addValue("space", reservation.spaceId()) + .addValue("project", reservation.projectNo()).addValue("version", versionValue(reservation.expectedVersion())) + .addValue("reservation", sqlId(reservation.reservationId())), (rs, row) -> reservationResult(rs)); + } + + private ReservationResult releaseSqlServer(String warehouseId, String reservationId) { + return named.queryForObject("EXEC " + dialect.releaseProcedure() + + " @warehouse_id=:warehouse, @reservation_id=:reservation", + new MapSqlParameterSource().addValue("warehouse", warehouseId) + .addValue("reservation", sqlId(reservationId)), (rs, row) -> reservationResult(rs)); + } + + private ReservationResult reservationResult(ResultSet rs) throws SQLException { + String result = rs.getString("result"); + String id = rs.getString("reservation_id"); + return switch (result) { + case "RESERVED" -> ReservationResult.reserved(id); + case "RELEASED" -> ReservationResult.released(id); + case "NOT_FOUND" -> ReservationResult.notFound(id); + default -> ReservationResult.conflict(rs.getString("reason"), id); + }; + } + + private SpaceSnapshot mapSpace(RawSpace raw, int capacity, VersionToken version, List inventory) { + EnumSet conflicts = EnumSet.noneOf(SpaceConflict.class); + if (raw.trayConflict()) conflicts.add(SpaceConflict.TRAY); + if (raw.projectConflict()) conflicts.add(SpaceConflict.PROJECT); + String inventoryTray = unique(inventory, InventoryItem::trayNo); + String tray = blankToNull(raw.spaceTrayNo()) != null ? raw.spaceTrayNo() : inventoryTray; + if (blankToNull(raw.spaceTrayNo()) != null && inventoryTray != null && !raw.spaceTrayNo().equals(inventoryTray)) { + conflicts.add(SpaceConflict.SPACE_TRAY_MISMATCH); + } + String project = unique(inventory, InventoryItem::projectNo); + String product = unique(inventory, InventoryItem::productNo); + String lot = unique(inventory, InventoryItem::lotNo); + Instant inboundAt = inventory.stream().map(InventoryItem::inboundAt).filter(Objects::nonNull) + .min(Comparator.naturalOrder()).orElse(null); + boolean invalid = locked(raw.locked()) || raw.reserved() || raw.hasGap() || raw.depth() == null + || !conflicts.isEmpty() || ("1".equals(raw.spaceStatus()) && (!inventory.isEmpty() || tray != null)); + SpaceStatus status = invalid ? SpaceStatus.DISABLED : switch (Objects.toString(raw.spaceStatus(), "")) { + case "1" -> SpaceStatus.EMPTY; + case "2" -> SpaceStatus.OCCUPIED; + default -> SpaceStatus.DISABLED; + }; + SpaceState state = new SpaceState(raw.spaceId(), raw.zoneCode(), raw.laneCode(), + raw.depth() == null ? 0 : raw.depth(), capacity, raw.floorNo(), raw.columnNo(), + raw.depth() == null ? 0 : raw.depth(), raw.platoon() == null ? null : raw.platoon().toString(), + mapRole(raw.role()), status, + raw.pendingOutbound(), !conflicts.isEmpty(), tray, project, product, lot, inboundAt, null, + raw.reserved(), version == null ? null : version.externalForm(), !inventory.isEmpty()); + String diagnostic = invalid ? diagnostic(raw, conflicts) : null; + return new SpaceSnapshot(state, inventory, conflicts, raw.inboundAvailable(), raw.hasGap(), diagnostic); + } + + private String diagnostic(RawSpace raw, Set conflicts) { + if (!conflicts.isEmpty()) return "INVENTORY_CONFLICT:" + conflicts; + if (raw.reserved()) return "RESERVED"; + if (raw.hasGap()) return "LANE_GAP"; + if (raw.depth() == null) return "INVALID_TOPOLOGY"; + if (locked(raw.locked())) return "LOCKED"; + return "NON_AVAILABLE_STATUS:" + raw.spaceStatus(); + } + + private SpaceRole mapRole(String role) { + return switch (role) { + case "STORAGE" -> SpaceRole.STORAGE; + case "RELOCATION_BUFFER" -> SpaceRole.RELOCATION_BUFFER; + case "OUTBOUND_BUFFER" -> SpaceRole.OUTBOUND_CACHE; + case "PROTECTED_CORE" -> SpaceRole.PROTECTED_CORE; + default -> throw new IllegalStateException("Unknown space role: " + role); + }; + } + + private RowMapper laneCandidateMapper() { + return (rs, row) -> new LaneCandidate(rs.getString("warehouse_id"), rs.getString("lane_code"), + rs.getInt("space_count"), rs.getInt("occupied_count"), rs.getInt("available_count"), + rs.getBoolean("pending_outbound"), rs.getBoolean("has_gap"), + VersionToken.fromJdbc(rs.getObject("state_version"))); + } + + private RowMapper rawSpaceMapper() { + return (rs, row) -> new RawSpace(rs.getString("space_id"), rs.getString("lane_code"), + rs.getString("area_id"), rs.getString("zone_code"), rs.getString("roadway_id"), + nullableInt(rs, "platoon"), rs.getInt("column_no"), rs.getInt("floor_no"), + nullableInt(rs, "depth"), rs.getString("space_status"), + rs.getString("locked"), rs.getString("space_tray_code"), rs.getString("role"), + rs.getBoolean("tray_conflict"), rs.getBoolean("project_conflict"), + rs.getBoolean("product_conflict"), rs.getBoolean("pending_outbound"), + rs.getBoolean("reserved"), rs.getBoolean("has_gap"), rs.getBoolean("inbound_available")); + } + + private RowMapper inventoryMapper() { + return (rs, row) -> new InventoryItem(rs.getString("stock_id"), rs.getString("space_id"), + rs.getString("tray_code"), rs.getString("project_no"), rs.getString("product_no"), + rs.getString("lot_no"), rs.getString("inbound_time_raw"), instant(rs, "inbound_at"), + rs.getBigDecimal("quantity"), rs.getBigDecimal("out_quantity")); + } + + private Object sqlId(String id) { + UUID value = UUID.fromString(id); + return dialect.h2Database() ? value.toString() : value; + } + private void validateWorkflowLock(String requestId, String warehouseId, int floorNo) { + if (blankToNull(requestId) == null) throw new IllegalArgumentException("requestId is required"); + if (blankToNull(warehouseId) == null) throw new IllegalArgumentException("warehouseId is required"); + if (floorNo <= 0) throw new IllegalArgumentException("floorNo must be positive"); + } + private Object versionValue(VersionToken token) { return token == null ? null : token.jdbcValue(); } + + static int decisionVersionSqlType(RepositoryDialect dialect) { + return dialect.h2Database() ? Types.BIGINT : Types.BINARY; + } + private String abbreviate(String value, int maximum) { + return value == null || value.length() <= maximum ? value : value.substring(0, maximum); + } + private boolean locked(String value) { + String normalized = blankToNull(value); + return normalized != null && !"0".equalsIgnoreCase(normalized) && !"N".equalsIgnoreCase(normalized); + } + private String blankToEmpty(String value) { return value == null ? "" : value; } + private String blankToNull(String value) { return value == null || value.isBlank() ? null : value; } + private Integer nullableInt(ResultSet rs, String column) throws SQLException { + int value = rs.getInt(column); + return rs.wasNull() ? null : value; + } + private Instant instant(ResultSet rs, String column) throws SQLException { + Timestamp timestamp = rs.getTimestamp(column); + return timestamp == null ? null : timestamp.toInstant(); + } + private String unique(List values, Function extractor) { + Set distinct = values.stream().map(extractor).map(this::blankToNull) + .filter(Objects::nonNull).collect(Collectors.toCollection(LinkedHashSet::new)); + return distinct.size() == 1 ? distinct.iterator().next() : null; + } + private long distinctCount(List values, Function extractor) { + return values.stream().map(extractor).map(this::blankToNull).filter(Objects::nonNull).distinct().count(); + } + + private record RawSpace(String spaceId, String laneCode, String areaId, String zoneCode, String roadwayId, + Integer platoon, int columnNo, int floorNo, Integer depth, String spaceStatus, + String locked, String spaceTrayNo, + String role, boolean trayConflict, boolean projectConflict, boolean productConflict, + boolean pendingOutbound, boolean reserved, boolean hasGap, boolean inboundAvailable) { + } + + private record LaneReservationState(VersionToken version, String semanticFingerprint) { + } + + private enum InventoryFingerprintSource { + SNAPSHOT, + LIVE + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/LaneCandidate.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/LaneCandidate.java new file mode 100644 index 0000000..1f7dd77 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/LaneCandidate.java @@ -0,0 +1,5 @@ +package com.ruoyi.algorithm.repository; + +public record LaneCandidate(String warehouseId, String laneCode, int spaceCount, int occupiedCount, + int availableCount, boolean pendingOutbound, boolean hasGap, VersionToken version) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/LanePage.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/LanePage.java new file mode 100644 index 0000000..d72295c --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/LanePage.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.repository; + +import java.util.List; + +public record LanePage(List lanes, String nextLaneCode) { + public LanePage { lanes = List.copyOf(lanes); } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/LaneSnapshot.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/LaneSnapshot.java new file mode 100644 index 0000000..70b6375 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/LaneSnapshot.java @@ -0,0 +1,10 @@ +package com.ruoyi.algorithm.repository; + +import com.ruoyi.algorithm.model.SpaceState; + +import java.util.List; + +public record LaneSnapshot(String warehouseId, String laneCode, VersionToken version, List spaces) { + public LaneSnapshot { spaces = List.copyOf(spaces); } + public List spaceStates() { return spaces.stream().map(SpaceSnapshot::state).toList(); } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/OutboundStockMatch.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/OutboundStockMatch.java new file mode 100644 index 0000000..aba77ab --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/OutboundStockMatch.java @@ -0,0 +1,8 @@ +package com.ruoyi.algorithm.repository; + +import java.time.Instant; + +public record OutboundStockMatch(String stockId, String spaceId, String laneCode, int floorNo, String trayNo, + String projectNo, String productNo, String lotNo, + String inboundTimeRaw, Instant inboundAt) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/OutboundStockSearch.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/OutboundStockSearch.java new file mode 100644 index 0000000..17f1645 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/OutboundStockSearch.java @@ -0,0 +1,13 @@ +package com.ruoyi.algorithm.repository; + +public record OutboundStockSearch(String trayNo, String projectNo, String productNo) { + public OutboundStockSearch { + boolean hasTray = trayNo != null && !trayNo.isBlank(); + boolean hasProject = projectNo != null && !projectNo.isBlank(); + if (hasTray == hasProject) throw new IllegalArgumentException("Specify exact tray or project, but not both"); + } + public static OutboundStockSearch exactTray(String trayNo) { return new OutboundStockSearch(trayNo, null, null); } + public static OutboundStockSearch project(String projectNo, String productNo) { + return new OutboundStockSearch(null, projectNo, productNo); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/PendingOutboundJob.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/PendingOutboundJob.java new file mode 100644 index 0000000..205f2c4 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/PendingOutboundJob.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.repository; + +public record PendingOutboundJob(String jobId, String taskNo, String trayNo, String projectNo, + String productNo, String sourceSpaceId, String warehouseId, + String sourceLaneCode, String sourceResolution, String status, + int direction, String createTimeRaw) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/RepositoryDialect.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/RepositoryDialect.java new file mode 100644 index 0000000..925028b --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/RepositoryDialect.java @@ -0,0 +1,74 @@ +package com.ruoyi.algorithm.repository; + +public final class RepositoryDialect { + private final boolean h2Database; + private final String laneState; + private final String spaceStateView; + private final String inventoryView; + private final String activeJobView; + private final String warehousePolicy; + private final String projectPolicy; + private final String reservation; + private final String decisionLog; + private final String deepWorkflowLock; + private final String tryReserveProcedure; + private final String releaseProcedure; + private final String acquireDeepWorkflowProcedure; + private final String releaseDeepWorkflowProcedure; + private final String trueLiteral; + private final String falseLiteral; + + private RepositoryDialect(boolean h2Database, String laneState, String spaceStateView, String inventoryView, + String activeJobView, String warehousePolicy, String projectPolicy, + String reservation, String decisionLog, String deepWorkflowLock, + String tryReserveProcedure, String releaseProcedure, + String acquireDeepWorkflowProcedure, String releaseDeepWorkflowProcedure, + String trueLiteral, String falseLiteral) { + this.h2Database = h2Database; + this.laneState = laneState; + this.spaceStateView = spaceStateView; + this.inventoryView = inventoryView; + this.activeJobView = activeJobView; + this.warehousePolicy = warehousePolicy; + this.projectPolicy = projectPolicy; + this.reservation = reservation; + this.decisionLog = decisionLog; + this.deepWorkflowLock = deepWorkflowLock; + this.tryReserveProcedure = tryReserveProcedure; + this.releaseProcedure = releaseProcedure; + this.acquireDeepWorkflowProcedure = acquireDeepWorkflowProcedure; + this.releaseDeepWorkflowProcedure = releaseDeepWorkflowProcedure; + this.trueLiteral = trueLiteral; + this.falseLiteral = falseLiteral; + } + public static RepositoryDialect h2() { + return new RepositoryDialect(true, "ALG_LANE_STATE", "ALG_V_SPACE_STATE", "ALG_V_INVENTORY_ITEM", + "ALG_V_ACTIVE_JOB", "ALG_WAREHOUSE_POLICY", "ALG_PROJECT_POLICY", "ALG_RESERVATION", + "ALG_DECISION_LOG", "ALG_DEEP_WORKFLOW_LOCK", null, null, null, null, "TRUE", "FALSE"); + } + + public static RepositoryDialect sqlServer() { + return new RepositoryDialect(false, "alg.lane_state", "alg.v_space_state", "alg.v_inventory_item", + "alg.v_active_job", "alg.warehouse_policy", "alg.project_policy", "alg.reservation", + "alg.decision_log", "alg.deep_workflow_lock", "alg.usp_try_reserve_inbound", + "alg.usp_release_reservation", "alg.usp_acquire_deep_workflow_lock", + "alg.usp_release_deep_workflow_lock", "1", "0"); + } + + public boolean h2Database() { return h2Database; } + public String laneState() { return laneState; } + public String spaceStateView() { return spaceStateView; } + public String inventoryView() { return inventoryView; } + public String activeJobView() { return activeJobView; } + public String warehousePolicy() { return warehousePolicy; } + public String projectPolicy() { return projectPolicy; } + public String reservation() { return reservation; } + public String decisionLog() { return decisionLog; } + public String deepWorkflowLock() { return deepWorkflowLock; } + public String tryReserveProcedure() { return tryReserveProcedure; } + public String releaseProcedure() { return releaseProcedure; } + public String acquireDeepWorkflowProcedure() { return acquireDeepWorkflowProcedure; } + public String releaseDeepWorkflowProcedure() { return releaseDeepWorkflowProcedure; } + public String trueLiteral() { return trueLiteral; } + public String falseLiteral() { return falseLiteral; } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/RepositoryPolicy.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/RepositoryPolicy.java new file mode 100644 index 0000000..240fac9 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/RepositoryPolicy.java @@ -0,0 +1,11 @@ +package com.ruoyi.algorithm.repository; + +import com.ruoyi.algorithm.inbound.InboundPolicy; +import com.ruoyi.algorithm.policy.SchedulingPolicy; + +public record RepositoryPolicy(InboundPolicy inboundPolicy, SchedulingPolicy schedulingPolicy, + int fifoToleranceMinutes, double targetFillRate) { + public static RepositoryPolicy defaults() { + return new RepositoryPolicy(InboundPolicy.defaults(), SchedulingPolicy.ft546Defaults(), 0, 0.0); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/ReservationResult.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/ReservationResult.java new file mode 100644 index 0000000..541fa7f --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/ReservationResult.java @@ -0,0 +1,8 @@ +package com.ruoyi.algorithm.repository; + +public record ReservationResult(ReservationStatus status, String reasonCode, String reservationId) { + public static ReservationResult reserved(String id) { return new ReservationResult(ReservationStatus.RESERVED, null, id); } + public static ReservationResult conflict(String reason, String id) { return new ReservationResult(ReservationStatus.CONFLICT, reason, id); } + public static ReservationResult released(String id) { return new ReservationResult(ReservationStatus.RELEASED, null, id); } + public static ReservationResult notFound(String id) { return new ReservationResult(ReservationStatus.NOT_FOUND, "NOT_FOUND", id); } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/ReservationStatus.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/ReservationStatus.java new file mode 100644 index 0000000..2f2d163 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/ReservationStatus.java @@ -0,0 +1,3 @@ +package com.ruoyi.algorithm.repository; + +public enum ReservationStatus { RESERVED, CONFLICT, RELEASED, NOT_FOUND } diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/SpaceConflict.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/SpaceConflict.java new file mode 100644 index 0000000..0482e57 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/SpaceConflict.java @@ -0,0 +1,3 @@ +package com.ruoyi.algorithm.repository; + +public enum SpaceConflict { TRAY, PROJECT, PRODUCT, LOT, SPACE_TRAY_MISMATCH } diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/SpaceSnapshot.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/SpaceSnapshot.java new file mode 100644 index 0000000..66fa730 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/SpaceSnapshot.java @@ -0,0 +1,15 @@ +package com.ruoyi.algorithm.repository; + +import com.ruoyi.algorithm.model.SpaceState; + +import java.util.List; +import java.util.Set; + +public record SpaceSnapshot(SpaceState state, List inventory, Set conflicts, + boolean inboundAvailable, boolean hasGap, String diagnostic) { + public SpaceSnapshot { + inventory = List.copyOf(inventory); + conflicts = Set.copyOf(conflicts); + } + public String spaceId() { return state.spaceId(); } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/VersionToken.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/VersionToken.java new file mode 100644 index 0000000..5e399e2 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/VersionToken.java @@ -0,0 +1,50 @@ +package com.ruoyi.algorithm.repository; + +import java.util.Arrays; +import java.util.Base64; +import java.util.Objects; + +public final class VersionToken { + public enum Kind { NUMERIC, BINARY } + + private final Kind kind; + private final Long numeric; + private final byte[] binary; + + private VersionToken(Kind kind, Long numeric, byte[] binary) { + this.kind = kind; + this.numeric = numeric; + this.binary = binary == null ? null : binary.clone(); + } + + public static VersionToken numeric(long value) { + return new VersionToken(Kind.NUMERIC, value, null); + } + + public static VersionToken binary(byte[] value) { + Objects.requireNonNull(value, "value"); + return new VersionToken(Kind.BINARY, null, value); + } + + public static VersionToken fromJdbc(Object value) { + if (value == null) return null; + if (value instanceof byte[] bytes) return binary(bytes); + if (value instanceof Number number) return numeric(number.longValue()); + throw new IllegalArgumentException("Unsupported version token type: " + value.getClass().getName()); + } + + public Kind kind() { return kind; } + public Object jdbcValue() { return kind == Kind.BINARY ? binary.clone() : numeric; } + public String externalForm() { + return kind == Kind.BINARY ? Base64.getEncoder().encodeToString(binary) : Long.toString(numeric); + } + + @Override public boolean equals(Object other) { + if (this == other) return true; + if (!(other instanceof VersionToken token) || kind != token.kind) return false; + return Objects.equals(numeric, token.numeric) && Arrays.equals(binary, token.binary); + } + + @Override public int hashCode() { return 31 * Objects.hash(kind, numeric) + Arrays.hashCode(binary); } + @Override public String toString() { return externalForm(); } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/WarehouseRepository.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/WarehouseRepository.java new file mode 100644 index 0000000..af2def9 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/WarehouseRepository.java @@ -0,0 +1,39 @@ +package com.ruoyi.algorithm.repository; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +public interface WarehouseRepository { + void synchronizeReadModel(String warehouseId); + + default void refreshChangedLanes(String warehouseId) { + synchronizeReadModel(warehouseId); + } + + WarehouseSummary loadSummary(String warehouseId); + LanePage pageCandidateLanes(String warehouseId, String afterLaneCode, int pageSize); + LanePage pageWarehouseLanes(String warehouseId, String afterLaneCode, int pageSize); + List loadLaneSnapshots(String warehouseId, Collection laneCodes); + List loadRelocationBuffers(String warehouseId, Set floors); + Set loadActiveDeepWorkflowFloors(String warehouseId, String excludingRequestId); + boolean acquireDeepWorkflowLock(String requestId, String warehouseId, int floorNo); + boolean releaseDeepWorkflowLock(String requestId, String warehouseId, int floorNo); + default DeepWorkflowMutationResult acquireDeepWorkflowLockResult(String requestId, String warehouseId, int floorNo) { + return acquireDeepWorkflowLock(requestId, warehouseId, floorNo) + ? DeepWorkflowMutationResult.succeeded() : DeepWorkflowMutationResult.unchanged(); + } + default DeepWorkflowMutationResult releaseDeepWorkflowLockResult(String requestId, String warehouseId, int floorNo) { + return releaseDeepWorkflowLock(requestId, warehouseId, floorNo) + ? DeepWorkflowMutationResult.succeeded() : DeepWorkflowMutationResult.unchanged(); + } + List loadPendingOutboundJobs(String warehouseId); + List searchOutboundStock(String warehouseId, OutboundStockSearch search); + int countProjectPallets(String warehouseId, String projectNo); + RepositoryPolicy loadPolicy(String warehouseId); + DecisionLogEntry insertDecision(DecisionLogRecord record); + Optional findDecision(String decisionId); + ReservationResult tryReserveInbound(InboundReservation reservation); + ReservationResult releaseReservation(String warehouseId, String reservationId); +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/WarehouseSummary.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/WarehouseSummary.java new file mode 100644 index 0000000..e968c6d --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/repository/WarehouseSummary.java @@ -0,0 +1,6 @@ +package com.ruoyi.algorithm.repository; + +public record WarehouseSummary(String warehouseId, int laneCount, int spaceCount, int occupiedCount, + int availableCount, int pendingLaneCount, int conflictSpaceCount, + int reservedSpaceCount) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/service/InboundPlanningResult.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/service/InboundPlanningResult.java new file mode 100644 index 0000000..4070524 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/service/InboundPlanningResult.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.service; + +import com.ruoyi.algorithm.inbound.InboundPlan; +import com.ruoyi.algorithm.repository.VersionToken; + +public record InboundPlanningResult(InboundPlan plan, VersionToken laneVersion) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/service/InboundReservationOutcome.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/service/InboundReservationOutcome.java new file mode 100644 index 0000000..3ce1133 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/service/InboundReservationOutcome.java @@ -0,0 +1,6 @@ +package com.ruoyi.algorithm.service; + +import com.ruoyi.algorithm.repository.ReservationResult; + +public record InboundReservationOutcome(String resultCode, ReservationResult reservation) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/service/WarehouseApplicationService.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/service/WarehouseApplicationService.java new file mode 100644 index 0000000..3c0564f --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/service/WarehouseApplicationService.java @@ -0,0 +1,295 @@ +package com.ruoyi.algorithm.service; + +import com.ruoyi.algorithm.inbound.InboundContext; +import com.ruoyi.algorithm.inbound.InboundPlan; +import com.ruoyi.algorithm.inbound.InboundPlanner; +import com.ruoyi.algorithm.inbound.InboundRequest; +import com.ruoyi.algorithm.inbound.PendingOutbound; +import com.ruoyi.algorithm.model.SpaceState; +import com.ruoyi.algorithm.outbound.OutboundCapacityMode; +import com.ruoyi.algorithm.outbound.OutboundContext; +import com.ruoyi.algorithm.outbound.OutboundError; +import com.ruoyi.algorithm.outbound.OutboundErrorCode; +import com.ruoyi.algorithm.outbound.OutboundPlan; +import com.ruoyi.algorithm.outbound.OutboundPlanner; +import com.ruoyi.algorithm.outbound.OutboundRequest; +import com.ruoyi.algorithm.tidy.TidyPendingOutbound; +import com.ruoyi.algorithm.tidy.TidyPlan; +import com.ruoyi.algorithm.tidy.TidyPlanner; +import com.ruoyi.algorithm.tidy.TidyRequest; +import com.ruoyi.algorithm.repository.DecisionLogRecord; +import com.ruoyi.algorithm.repository.DeepWorkflowMutationResult; +import com.ruoyi.algorithm.repository.InboundReservation; +import com.ruoyi.algorithm.repository.LaneCandidate; +import com.ruoyi.algorithm.repository.LanePage; +import com.ruoyi.algorithm.repository.LaneSnapshot; +import com.ruoyi.algorithm.repository.OutboundStockMatch; +import com.ruoyi.algorithm.repository.OutboundStockSearch; +import com.ruoyi.algorithm.repository.PendingOutboundJob; +import com.ruoyi.algorithm.repository.RepositoryPolicy; +import com.ruoyi.algorithm.repository.ReservationResult; +import com.ruoyi.algorithm.repository.ReservationStatus; +import com.ruoyi.algorithm.repository.SpaceSnapshot; +import com.ruoyi.algorithm.repository.VersionToken; +import com.ruoyi.algorithm.repository.WarehouseRepository; +import com.ruoyi.algorithm.repository.WarehouseSummary; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; + +public final class WarehouseApplicationService { + private final WarehouseRepository repository; + private final InboundPlanner inboundPlanner; + private final OutboundPlanner outboundPlanner; + private final TidyPlanner tidyPlanner; + private final int pageSize; + + public WarehouseApplicationService(WarehouseRepository repository, InboundPlanner inboundPlanner, + OutboundPlanner outboundPlanner, TidyPlanner tidyPlanner, int pageSize) { + this.repository = Objects.requireNonNull(repository, "repository"); + this.inboundPlanner = Objects.requireNonNull(inboundPlanner, "inboundPlanner"); + this.outboundPlanner = Objects.requireNonNull(outboundPlanner, "outboundPlanner"); + this.tidyPlanner = Objects.requireNonNull(tidyPlanner, "tidyPlanner"); + this.pageSize = Math.max(1, Math.min(200, pageSize)); + } + + public WarehouseSummary summary(String warehouseId) { + return repository.loadSummary(warehouseId); + } + + public WarehouseDiagnostics diagnostics(String warehouseId) { + WarehouseSummary summary = repository.loadSummary(warehouseId); + List issues = new ArrayList<>(); + forEachLanePage(warehouseId, false, snapshots -> snapshots.stream() + .flatMap(lane -> lane.spaces().stream()) + .filter(space -> space.diagnostic() != null) + .forEach(space -> issues.add(space.spaceId() + ":" + space.diagnostic()))); + return new WarehouseDiagnostics(summary, issues.stream().sorted().toList()); + } + + public InboundPlanningResult planInbound(String warehouseId, InboundRequest request) { + repository.refreshChangedLanes(warehouseId); + RepositoryPolicy policy = repository.loadPolicy(warehouseId); + WarehouseSummary summary = repository.loadSummary(warehouseId); + InboundRequest effectiveRequest = request; + if (request.expectedProjectPallets() == null && nonBlank(request.projectNo())) { + int currentProjectPallets = repository.countProjectPallets(warehouseId, request.projectNo()); + effectiveRequest = new InboundRequest(request.requestId(), request.trayNo(), request.projectNo(), + request.productId(), request.lotNo(), currentProjectPallets <= 1 ? 2 : 4, + request.entryFloor(), request.targetFloor(), request.allowedFloors(), request.batchLaneMode()); + } + List pending = repository.loadPendingOutboundJobs(warehouseId).stream() + .map(job -> new PendingOutbound(job.projectNo(), job.productNo(), job.trayNo(), + job.sourceLaneCode(), job.sourceResolution())).toList(); + InboundPlanner.PagedSession session = inboundPlanner.startPaged(effectiveRequest, + policy.inboundPolicy(), pending, summary.occupiedCount()); + Map versions = new LinkedHashMap<>(); + String cursor = null; + do { + LanePage page = repository.pageCandidateLanes(warehouseId, cursor, pageSize); + List laneCodes = page.lanes().stream().map(LaneCandidate::laneCode).toList(); + if (!laneCodes.isEmpty()) { + List snapshots = repository.loadLaneSnapshots(warehouseId, laneCodes); + snapshots.forEach(lane -> versions.put(lane.laneCode(), lane.version())); + session.accept(snapshots.stream().flatMap(lane -> lane.spaceStates().stream()).toList()); + versions.keySet().retainAll(session.retainedLaneCodes()); + } + cursor = page.nextLaneCode(); + } while (cursor != null); + InboundPlan plan = session.finish(); + VersionToken version = plan.assignment().map(value -> versions.get(value.laneCode())).orElse(null); + String resultCode = plan.assignment().isPresent() ? "READY" + : "REJECTED_" + plan.rejection().orElseThrow().code().name(); + String reason = plan.assignment().map(value -> value.reason()) + .orElseGet(() -> plan.rejection().orElseThrow().reason()); + log(warehouseId, "INBOUND", version, resultCode, reason); + return new InboundPlanningResult(plan, version); + } + + public OutboundPlan planOutbound(String warehouseId, OutboundRequest request) { + repository.refreshChangedLanes(warehouseId); + RepositoryPolicy policy = repository.loadPolicy(warehouseId); + WarehouseSummary summary = repository.loadSummary(warehouseId); + OutboundRequest effectiveRequest = request.fifoToleranceMinutes() == null && policy.fifoToleranceMinutes() > 0 + ? new OutboundRequest(request.requestId(), request.trayNo(), request.projectNo(), request.productId(), + request.fifoMode(), policy.fifoToleranceMinutes(), request.exitFloor(), request.wholeTray()) + : request; + List matches = new ArrayList<>(); + String matchedProductScope = null; + if (nonBlank(request.trayNo())) { + matches.addAll(repository.searchOutboundStock(warehouseId, OutboundStockSearch.exactTray(request.trayNo()))); + boolean fifoEnabled = nonBlank(request.fifoMode()) && !"OFF".equalsIgnoreCase(request.fifoMode()); + Set spaces = matches.stream().map(OutboundStockMatch::spaceId).filter(this::nonBlank) + .collect(java.util.stream.Collectors.toCollection(LinkedHashSet::new)); + Set projects = matches.stream().map(OutboundStockMatch::projectNo).filter(this::nonBlank) + .collect(java.util.stream.Collectors.toCollection(LinkedHashSet::new)); + Set products = matches.stream().map(OutboundStockMatch::productNo).filter(this::nonBlank) + .collect(java.util.stream.Collectors.toCollection(LinkedHashSet::new)); + if (spaces.size() > 1 || projects.size() > 1) { + OutboundPlan ambiguous = OutboundPlan.error(new OutboundError(OutboundErrorCode.AMBIGUOUS_TRAY, + "Exact tray resolves to multiple spaces or inventory scopes.", + Map.of("spaceCount", spaces.size(), "projectCount", projects.size(), + "productCount", products.size()))); + log(warehouseId, "OUTBOUND", null, "ERROR_AMBIGUOUS_TRAY", + ambiguous.error().orElseThrow().message()); + return ambiguous; + } + if (fifoEnabled && projects.size() == 1) { + String project = projects.iterator().next(); + String product = products.size() == 1 ? products.iterator().next() : null; + matchedProductScope = product; + List scoped = repository.searchOutboundStock(warehouseId, + OutboundStockSearch.project(project, product)); + scoped.forEach(match -> { + if (matches.stream().noneMatch(existing -> existing.stockId().equals(match.stockId()))) { + matches.add(match); + } + }); + } + } else if (nonBlank(request.projectNo())) { + matchedProductScope = nonBlank(request.productId()) ? request.productId() : null; + matches.addAll(repository.searchOutboundStock(warehouseId, + OutboundStockSearch.project(request.projectNo(), request.productId()))); + } + List laneCodes = matches.stream().map(OutboundStockMatch::laneCode).filter(Objects::nonNull) + .distinct().sorted().toList(); + List lanes = repository.loadLaneSnapshots(warehouseId, laneCodes); + Set floors = matches.stream().map(OutboundStockMatch::floorNo) + .collect(java.util.stream.Collectors.toCollection(LinkedHashSet::new)); + List buffers = repository.loadRelocationBuffers(warehouseId, floors); + Map uniqueSpaces = new LinkedHashMap<>(); + Set matchedSpaceIds = matches.stream().map(OutboundStockMatch::spaceId) + .filter(this::nonBlank).collect(java.util.stream.Collectors.toSet()); + String productScope = matchedProductScope; + lanes.stream().flatMap(lane -> lane.spaceStates().stream()).forEach(space -> uniqueSpaces.put(space.spaceId(), + productScope != null && matchedSpaceIds.contains(space.spaceId()) + ? withProductScope(space, productScope) : space)); + buffers.stream().map(SpaceSnapshot::state).forEach(space -> uniqueSpaces.put(space.spaceId(), space)); + Map rawInboundTimes = new LinkedHashMap<>(); + matches.stream().filter(match -> match.inboundTimeRaw() != null) + .forEach(match -> rawInboundTimes.putIfAbsent(match.spaceId(), match.inboundTimeRaw())); + lanes.stream().flatMap(lane -> lane.spaces().stream()).forEach(space -> space.inventory().stream() + .filter(item -> item.inboundTimeRaw() != null) + .forEach(item -> rawInboundTimes.putIfAbsent(space.spaceId(), item.inboundTimeRaw()))); + OutboundPlan plan = outboundPlanner.plan(effectiveRequest, + new OutboundContext(List.copyOf(uniqueSpaces.values()), rawInboundTimes, + capacityMode(summary, policy), + repository.loadActiveDeepWorkflowFloors(warehouseId, request.requestId()))); + String resultCode = switch (plan.status()) { + case READY -> "READY"; + case WAITING -> "WAITING_" + plan.waiting().orElseThrow().code().name(); + case ERROR -> "ERROR_" + plan.error().orElseThrow().code().name(); + }; + String reason = plan.assignment().map(value -> value.reason()) + .or(() -> plan.waiting().map(value -> value.reason())) + .or(() -> plan.error().map(value -> value.message())).orElse(resultCode); + log(warehouseId, "OUTBOUND", null, resultCode, reason); + return plan; + } + + public TidyPlan planTidy(String warehouseId, Instant now) { + RepositoryPolicy policy = repository.loadPolicy(warehouseId); + List spaces = new ArrayList<>(); + forEachLanePage(warehouseId, false, + snapshots -> snapshots.forEach(lane -> spaces.addAll(lane.spaceStates()))); + List pending = repository.loadPendingOutboundJobs(warehouseId).stream() + .map(job -> new TidyPendingOutbound(job.projectNo(), job.productNo(), job.trayNo(), + job.sourceLaneCode())).toList(); + TidyPlan plan = tidyPlanner.plan(new TidyRequest(spaces, pending, now, + policy.schedulingPolicy(), policy.inboundPolicy().commonProjectNos())); + String result = plan.candidates().isEmpty() ? "EMPTY" : "READY"; + log(warehouseId, "TIDY", null, result, + plan.diagnostics().isEmpty() ? "candidates=" + plan.candidates().size() + : String.join("; ", plan.diagnostics())); + return plan; + } + + public InboundReservationOutcome reserveInbound(String reservationId, String warehouseId, String projectNo, + InboundPlanningResult planned) { + var assignment = planned.plan().assignment().orElseThrow( + () -> new IllegalArgumentException("Only an accepted inbound plan can be reserved")); + ReservationResult result = repository.tryReserveInbound(new InboundReservation(reservationId, warehouseId, + assignment.laneCode(), assignment.spaceId(), projectNo, planned.laneVersion())); + String resultCode = result.status() == ReservationStatus.CONFLICT ? "REPLAN_REQUIRED" : result.status().name(); + log(warehouseId, "INBOUND_RESERVATION", planned.laneVersion(), resultCode, + result.reasonCode() == null ? resultCode : result.reasonCode()); + return new InboundReservationOutcome(resultCode, result); + } + + public InboundReservationOutcome reserveInbound(InboundReservation reservation) { + ReservationResult result = repository.tryReserveInbound(reservation); + String resultCode = result.status() == ReservationStatus.CONFLICT ? "REPLAN_REQUIRED" : result.status().name(); + log(reservation.warehouseId(), "INBOUND_RESERVATION", reservation.expectedVersion(), resultCode, + result.reasonCode() == null ? resultCode : result.reasonCode()); + return new InboundReservationOutcome(resultCode, result); + } + + public ReservationResult releaseReservation(String warehouseId, String reservationId) { + ReservationResult result = repository.releaseReservation(warehouseId, reservationId); + log(warehouseId, "RESERVATION_RELEASE", null, result.status().name(), result.reasonCode()); + return result; + } + + public DeepWorkflowMutationResult acquireDeepWorkflowLock(String warehouseId, String requestId, int floorNo) { + DeepWorkflowMutationResult result = repository.acquireDeepWorkflowLockResult(requestId, warehouseId, floorNo); + log(warehouseId, "DEEP_WORKFLOW_LOCK", null, result.changed() ? "ACQUIRED" + : result.reasonCode() == null ? "CONFLICT" : result.reasonCode(), + "request=" + requestId + ", floor=" + floorNo); + return result; + } + + public DeepWorkflowMutationResult releaseDeepWorkflowLock(String warehouseId, String requestId, int floorNo) { + DeepWorkflowMutationResult result = repository.releaseDeepWorkflowLockResult(requestId, warehouseId, floorNo); + log(warehouseId, "DEEP_WORKFLOW_RELEASE", null, result.changed() ? "RELEASED" + : result.reasonCode() == null ? "NOT_FOUND" : result.reasonCode(), + "request=" + requestId + ", floor=" + floorNo); + return result; + } + + private void forEachLanePage(String warehouseId, boolean candidatesOnly, + java.util.function.Consumer> consumer) { + String cursor = null; + do { + LanePage page = candidatesOnly + ? repository.pageCandidateLanes(warehouseId, cursor, pageSize) + : repository.pageWarehouseLanes(warehouseId, cursor, pageSize); + List laneCodes = page.lanes().stream().map(LaneCandidate::laneCode).toList(); + if (!laneCodes.isEmpty()) consumer.accept(repository.loadLaneSnapshots(warehouseId, laneCodes)); + cursor = page.nextLaneCode(); + } while (cursor != null); + } + + private void log(String warehouseId, String type, VersionToken version, String resultCode, String reason) { + repository.insertDecision(new DecisionLogRecord(UUID.randomUUID().toString(), warehouseId, type, + version, resultCode, reason)); + } + + private OutboundCapacityMode capacityMode(WarehouseSummary summary, RepositoryPolicy policy) { + int occupied = summary.occupiedCount(); + if (occupied >= policy.schedulingPolicy().capacityFirstOccupied()) { + return OutboundCapacityMode.CAPACITY_FIRST; + } + if (occupied >= policy.schedulingPolicy().warningOccupied()) { + return OutboundCapacityMode.WARNING; + } + return OutboundCapacityMode.BALANCED; + } + + private SpaceState withProductScope(SpaceState space, String productId) { + return new SpaceState(space.spaceId(), space.zoneCode(), space.laneCode(), space.depthOrder(), + space.laneCapacity(), space.floorNo(), space.aisleNo(), space.groupCoding(), space.rowCode(), + space.role(), space.status(), space.outboundTaskActive(), space.inventoryProjectConflict(), + space.trayNo(), space.projectNo(), productId, space.lotNo(), space.inboundAt(), space.outboundAt(), + space.reserved(), space.rowVersion(), space.physicalStockPresent()); + } + + private boolean nonBlank(String value) { return value != null && !value.isBlank(); } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/service/WarehouseDiagnostics.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/service/WarehouseDiagnostics.java new file mode 100644 index 0000000..fe000d4 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/service/WarehouseDiagnostics.java @@ -0,0 +1,9 @@ +package com.ruoyi.algorithm.service; + +import com.ruoyi.algorithm.repository.WarehouseSummary; + +import java.util.List; + +public record WarehouseDiagnostics(WarehouseSummary summary, List issues) { + public WarehouseDiagnostics { issues = List.copyOf(issues); } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyCandidate.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyCandidate.java new file mode 100644 index 0000000..e2627ce --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyCandidate.java @@ -0,0 +1,17 @@ +package com.ruoyi.algorithm.tidy; + +import java.util.List; +import java.util.Optional; + +public record TidyCandidate( + TidyCandidateType type, + String projectNo, + List moves, + Optional releasesLaneCode, + String reason +) { + public TidyCandidate { + moves = List.copyOf(moves); + releasesLaneCode = releasesLaneCode == null ? Optional.empty() : releasesLaneCode; + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyCandidateType.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyCandidateType.java new file mode 100644 index 0000000..141d4bc --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyCandidateType.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.tidy; + +public enum TidyCandidateType { + GUEST_RETURN, + DOWNGRADE_MERGE, + CONSOLIDATE_INCUBATION +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyMove.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyMove.java new file mode 100644 index 0000000..6b8e7a6 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyMove.java @@ -0,0 +1,4 @@ +package com.ruoyi.algorithm.tidy; + +public record TidyMove(String trayNo, String fromSpaceId, String toSpaceId) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyPendingOutbound.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyPendingOutbound.java new file mode 100644 index 0000000..1c937a5 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyPendingOutbound.java @@ -0,0 +1,4 @@ +package com.ruoyi.algorithm.tidy; + +public record TidyPendingOutbound(String projectNo, String productId, String trayNo, String laneCode) { +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyPlan.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyPlan.java new file mode 100644 index 0000000..daa6cae --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyPlan.java @@ -0,0 +1,10 @@ +package com.ruoyi.algorithm.tidy; + +import java.util.List; + +public record TidyPlan(List candidates, List diagnostics) { + public TidyPlan { + candidates = List.copyOf(candidates); + diagnostics = List.copyOf(diagnostics); + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyPlanner.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyPlanner.java new file mode 100644 index 0000000..ee45570 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyPlanner.java @@ -0,0 +1,358 @@ +package com.ruoyi.algorithm.tidy; + +import com.ruoyi.algorithm.model.SpaceRole; +import com.ruoyi.algorithm.model.SpaceState; + +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +public final class TidyPlanner { + private static final Duration STAGNANT_AGE = Duration.ofHours(72); + + public TidyPlan plan(TidyRequest request) { + Map lanes = laneViews(request.spaces()); + Set pendingLanes = pendingLaneCodes(request); + Set usedSources = new HashSet<>(); + Set usedTargets = new HashSet<>(); + List candidates = new ArrayList<>(); + List diagnostics = new ArrayList<>(); + Map newestInboundByProject = newestInboundByProject(request.spaces()); + + addGuestReturns(lanes, pendingLanes, usedSources, usedTargets, candidates); + if (request.now() == null) { + diagnostics.add("No current time supplied; DOWNGRADE_MERGE candidates were skipped"); + } else { + addDowngrades(lanes, pendingLanes, request.now(), newestInboundByProject, + request.commonProjectNos(), usedSources, usedTargets, candidates); + } + addConsolidations(lanes, pendingLanes, request.commonProjectNos(), + usedSources, usedTargets, candidates); + + candidates.sort(Comparator.comparingInt((TidyCandidate candidate) -> candidate.type().ordinal()) + .thenComparingInt(candidate -> candidate.releasesLaneCode().isPresent() ? 0 : 1) + .thenComparingInt(candidate -> candidate.moves().size()) + .thenComparing(TidyCandidate::projectNo, Comparator.nullsLast(String::compareTo))); + int maximum = Math.max(0, request.policy().maxTidyCandidates()); + if (candidates.size() > maximum) { + diagnostics.add("Tidy candidates exceeded policy maximum; retained first " + maximum); + candidates = new ArrayList<>(candidates.subList(0, maximum)); + } + return new TidyPlan(candidates, diagnostics); + } + + private void addGuestReturns(Map lanes, Set pendingLanes, + Set usedSources, Set usedTargets, + List candidates) { + lanes.values().stream().sorted(Comparator.comparing(LaneView::laneCode)).forEach(source -> { + if (source.corrupt() || source.guestProject() == null || pendingLanes.contains(source.laneCode()) + || laneTouched(source, usedSources, usedTargets)) return; + List guests = source.guestSpaces().stream() + .sorted(Comparator.comparingInt(SpaceState::groupCoding).reversed() + .thenComparing(SpaceState::spaceId)) + .toList(); + if (guests.stream().anyMatch(space -> usedSources.contains(space.spaceId()))) return; + LaneView target = lanes.values().stream() + .filter(lane -> !lane.laneCode().equals(source.laneCode())) + .filter(lane -> !lane.corrupt() && lane.guestProject() == null) + .filter(lane -> source.guestProject().equals(lane.residentProject())) + .filter(lane -> !pendingLanes.contains(lane.laneCode())) + .filter(lane -> !laneTouched(lane, usedSources, usedTargets)) + .filter(lane -> availableTargets(lane, usedTargets).size() >= guests.size()) + .min(Comparator.comparingInt((LaneView lane) -> Math.abs(lane.floorNo() - source.floorNo())) + .thenComparing(Comparator.comparingInt((LaneView lane) -> lane.occupied().size()).reversed()) + .thenComparing(LaneView::laneCode)) + .orElse(null); + if (target == null) { + target = fallbackGuestDestination(source, source.guestProject(), guests.size(), lanes, + pendingLanes, usedSources, usedTargets); + } + if (target == null) return; + List targetSpaces = availableTargets(target, usedTargets).subList(0, guests.size()); + List moves = moves(guests, targetSpaces); + reserve(moves, usedSources, usedTargets); + candidates.add(new TidyCandidate(TidyCandidateType.GUEST_RETURN, source.guestProject(), moves, + Optional.empty(), "Return guest project stock to its own lane")); + }); + } + + private void addDowngrades(Map lanes, Set pendingLanes, Instant now, + Map newestInboundByProject, Set commonProjectNos, + Set usedSources, Set usedTargets, + List candidates) { + Instant threshold = now.minus(STAGNANT_AGE); + lanes.values().stream().sorted(Comparator.comparing(LaneView::laneCode)).forEach(source -> { + if (source.capacity() != 5 || source.corrupt() || source.guestProject() != null + || source.residentProject() == null || source.occupied().isEmpty() + || source.occupied().size() > 2 || pendingLanes.contains(source.laneCode()) + || commonProjectNos.contains(source.residentProject()) + || laneTouched(source, usedSources, usedTargets)) return; + Instant projectNewest = newestInboundByProject.get(source.residentProject()); + if (projectNewest == null || projectNewest.isAfter(threshold)) return; + LaneView target = source.occupied().size() == 1 ? lanes.values().stream() + .filter(lane -> lane.capacity() == 1 && lane.occupied().isEmpty() && !lane.corrupt()) + .filter(lane -> singlePoolTier(lane) < 2) + .filter(lane -> !pendingLanes.contains(lane.laneCode())) + .filter(lane -> !laneTouched(lane, usedSources, usedTargets)) + .filter(lane -> availableTargets(lane, usedTargets).size() == 1) + .min(Comparator.comparingInt(this::singlePoolTier) + .thenComparingInt(lane -> Math.abs(lane.floorNo() - source.floorNo())) + .thenComparing(LaneView::laneCode)) + .orElse(null) : null; + if (target == null) target = lanes.values().stream() + .filter(lane -> lane.capacity() == 2 && lane.occupied().isEmpty() && !lane.corrupt()) + .filter(lane -> !pendingLanes.contains(lane.laneCode())) + .filter(lane -> !laneTouched(lane, usedSources, usedTargets)) + .filter(lane -> availableTargets(lane, usedTargets).size() >= source.occupied().size()) + .min(Comparator.comparingInt((LaneView lane) -> Math.abs(lane.floorNo() - source.floorNo())) + .thenComparing(LaneView::laneCode)) + .orElse(null); + if (target == null) return; + List ordered = source.occupied().stream() + .sorted(Comparator.comparingInt(SpaceState::groupCoding).reversed() + .thenComparing(SpaceState::spaceId)) + .toList(); + List moves = moves(ordered, + availableTargets(target, usedTargets).subList(0, ordered.size())); + reserve(moves, usedSources, usedTargets); + candidates.add(new TidyCandidate(TidyCandidateType.DOWNGRADE_MERGE, source.residentProject(), moves, + Optional.of(source.laneCode()), "Move stagnant stock to a shallower lane and release the deep lane")); + }); + } + + private void addConsolidations(Map lanes, Set pendingLanes, + Set commonProjectNos, + Set usedSources, Set usedTargets, + List candidates) { + Set projects = new HashSet<>(); + lanes.values().forEach(lane -> { + if (lane.capacity() == 5 && !lane.corrupt() && lane.guestProject() == null + && lane.residentProject() != null && !lane.occupied().isEmpty() + && lane.occupied().stream().noneMatch(space -> usedSources.contains(space.spaceId())) + && lane.spaces().stream().noneMatch(space -> usedTargets.contains(space.spaceId())) + && !commonProjectNos.contains(lane.residentProject()) + && !availableTargets(lane, usedTargets).isEmpty() && !pendingLanes.contains(lane.laneCode())) { + projects.add(lane.residentProject()); + } + }); + projects.stream().sorted().forEach(project -> { + if (commonProjectNos.contains(project)) return; + List deep = lanes.values().stream() + .filter(lane -> lane.capacity() == 5 && !lane.corrupt() && lane.guestProject() == null) + .filter(lane -> project.equals(lane.residentProject())) + .filter(lane -> lane.occupied().stream().noneMatch(space -> usedSources.contains(space.spaceId()))) + .filter(lane -> lane.spaces().stream().noneMatch(space -> usedTargets.contains(space.spaceId()))) + .filter(lane -> !pendingLanes.contains(lane.laneCode())) + .sorted(Comparator.comparingInt((LaneView lane) -> lane.occupied().size()).reversed() + .thenComparing(LaneView::laneCode)) + .toList(); + if (deep.isEmpty()) return; + List shallow = lanes.values().stream() + .filter(lane -> lane.capacity() <= 2 && !pendingLanes.contains(lane.laneCode())) + .filter(lane -> !laneTouched(lane, usedSources, usedTargets)) + .flatMap(lane -> accessibleInPhysicalOrder(lane).stream()) + .filter(space -> project.equals(space.projectNo())) + .filter(space -> !usedSources.contains(space.spaceId())) + .sorted(Comparator.comparing(SpaceState::laneCode) + .thenComparing(Comparator.comparingInt(SpaceState::groupCoding).reversed()) + .thenComparing(SpaceState::spaceId)) + .toList(); + if (shallow.isEmpty()) return; + List moves = new ArrayList<>(); + for (SpaceState source : shallow) { + SpaceState target = deep.stream().flatMap(lane -> availableTargets(lane, usedTargets).stream()) + .findFirst().orElse(null); + if (target == null) break; + TidyMove move = new TidyMove(source.trayNo(), source.spaceId(), target.spaceId()); + moves.add(move); + reserve(List.of(move), usedSources, usedTargets); + } + if (moves.isEmpty()) return; + Optional released = lanes.values().stream() + .filter(lane -> lane.capacity() <= 2) + .filter(lane -> lane.occupied().stream().allMatch(space -> usedSources.contains(space.spaceId()))) + .filter(lane -> lane.occupied().stream().anyMatch(space -> project.equals(space.projectNo()))) + .map(LaneView::laneCode).sorted().findFirst(); + candidates.add(new TidyCandidate(TidyCandidateType.CONSOLIDATE_INCUBATION, project, moves, released, + "Consolidate accessible shallow stock into a current deep project lane")); + }); + } + + private LaneView fallbackGuestDestination(LaneView source, String projectNo, int requiredSlots, + Map lanes, Set pendingLanes, + Set usedSources, Set usedTargets) { + int projectPallets = (int) lanes.values().stream() + .flatMap(lane -> lane.occupied().stream()) + .filter(space -> projectNo.equals(space.projectNo())) + .count(); + int[] depthOrder = projectPallets >= 2 ? new int[]{5, 3, 2} : new int[]{2, 3}; + for (int depth : depthOrder) { + LaneView empty = lanes.values().stream() + .filter(lane -> lane.capacity() == depth && lane.occupied().isEmpty() && !lane.corrupt()) + .filter(lane -> !pendingLanes.contains(lane.laneCode())) + .filter(lane -> !laneTouched(lane, usedSources, usedTargets)) + .filter(lane -> lane.spaces().stream().allMatch(this::ordinaryAvailableStorage)) + .filter(lane -> availableTargets(lane, usedTargets).size() >= requiredSlots) + .min(Comparator.comparingInt((LaneView lane) -> Math.abs(lane.floorNo() - source.floorNo())) + .thenComparing(LaneView::laneCode)) + .orElse(null); + if (empty != null) return empty; + } + if (requiredSlots != 1) return null; + return lanes.values().stream() + .filter(lane -> lane.capacity() == 1 && lane.occupied().isEmpty() && !lane.corrupt()) + .filter(lane -> !pendingLanes.contains(lane.laneCode())) + .filter(lane -> !laneTouched(lane, usedSources, usedTargets)) + .filter(lane -> lane.spaces().stream().allMatch(this::ordinaryAvailableStorage)) + .min(Comparator.comparingInt(this::singlePoolTier) + .thenComparingInt(lane -> Math.abs(lane.floorNo() - source.floorNo())) + .thenComparing(LaneView::laneCode)) + .orElse(null); + } + + private boolean ordinaryAvailableStorage(SpaceState space) { + return space.role() == SpaceRole.STORAGE && space.availableEmpty(); + } + + private int singlePoolTier(LaneView lane) { + String zone = lane.spaces().get(0).zoneCode(); + if ("FLEX".equals(zone)) return 0; + if ("CACHE".equals(zone)) return 1; + return 2; + } + + private boolean laneTouched(LaneView lane, Set usedSources, Set usedTargets) { + return lane.spaces().stream().anyMatch(space -> usedSources.contains(space.spaceId()) + || usedTargets.contains(space.spaceId())); + } + + private Map newestInboundByProject(List spaces) { + Map result = new HashMap<>(); + spaces.stream().filter(SpaceState::occupied) + .filter(space -> !blank(space.projectNo()) && space.inboundAt() != null) + .forEach(space -> result.merge(space.projectNo(), space.inboundAt(), + (left, right) -> left.isAfter(right) ? left : right)); + return result; + } + + private List accessibleInPhysicalOrder(LaneView lane) { + if (lane.corrupt() || lane.occupied().isEmpty()) return List.of(); + return lane.occupied().stream() + .sorted(Comparator.comparingInt(SpaceState::groupCoding).reversed() + .thenComparing(SpaceState::spaceId)) + .toList(); + } + + private List moves(List sources, List targets) { + List result = new ArrayList<>(); + for (int index = 0; index < sources.size(); index++) { + result.add(new TidyMove(sources.get(index).trayNo(), sources.get(index).spaceId(), targets.get(index).spaceId())); + } + return result; + } + + private void reserve(List moves, Set usedSources, Set usedTargets) { + moves.forEach(move -> { + usedSources.add(move.fromSpaceId()); + usedTargets.add(move.toSpaceId()); + }); + } + + private List availableTargets(LaneView lane, Set usedTargets) { + if (lane.corrupt()) return List.of(); + return lane.spaces().stream() + .filter(space -> space.groupCoding() > lane.occupied().size()) + .filter(space -> space.role() == SpaceRole.STORAGE && space.availableEmpty()) + .filter(space -> !usedTargets.contains(space.spaceId())) + .sorted(Comparator.comparingInt(SpaceState::groupCoding).thenComparing(SpaceState::spaceId)) + .toList(); + } + + private Set pendingLaneCodes(TidyRequest request) { + Set result = new HashSet<>(); + request.spaces().stream().filter(SpaceState::outboundTaskActive) + .map(SpaceState::laneCode).forEach(result::add); + for (TidyPendingOutbound pending : request.pendingOutbounds()) { + if (!blank(pending.laneCode())) result.add(pending.laneCode()); + request.spaces().stream().filter(SpaceState::occupied).filter(space -> pendingMatches(space, pending)) + .map(SpaceState::laneCode).forEach(result::add); + } + return result; + } + + private boolean pendingMatches(SpaceState space, TidyPendingOutbound pending) { + if (!blank(pending.trayNo())) return pending.trayNo().equals(space.trayNo()); + if (blank(pending.projectNo())) return false; + return pending.projectNo().equals(space.projectNo()) + && (blank(pending.productId()) || pending.productId().equals(space.productId())); + } + + private Map laneViews(List spaces) { + Map> grouped = new LinkedHashMap<>(); + spaces.forEach(space -> grouped.computeIfAbsent(space.laneCode(), ignored -> new ArrayList<>()).add(space)); + Map result = new HashMap<>(); + grouped.forEach((laneCode, members) -> result.put(laneCode, analyze(laneCode, members))); + return result; + } + + private LaneView analyze(String laneCode, List members) { + List ordered = members.stream() + .sorted(Comparator.comparingInt(SpaceState::groupCoding).thenComparing(SpaceState::spaceId)) + .toList(); + int capacity = ordered.stream().mapToInt(SpaceState::laneCapacity).max().orElse(0); + List occupied = ordered.stream().filter(SpaceState::occupied).toList(); + boolean corrupt = ordered.size() != capacity; + boolean emptySeen = false; + List segments = new ArrayList<>(); + String last = null; + for (SpaceState space : ordered) { + if (!space.occupied()) { + emptySeen = true; + continue; + } + if (emptySeen || space.inventoryProjectConflict() || !space.outboundSelectable()) corrupt = true; + String projectNo = space.projectNo(); + if (blank(projectNo)) { + corrupt = true; + continue; + } + if (!projectNo.equals(last)) { + segments.add(projectNo); + last = projectNo; + } + } + if (segments.size() > 2) corrupt = true; + String resident = segments.isEmpty() ? null : segments.get(0); + String guest = segments.size() < 2 ? null : segments.get(1); + String finalGuest = guest; + List guests = guest == null ? List.of() + : occupied.stream().filter(space -> finalGuest.equals(space.projectNo())).toList(); + int floor = ordered.isEmpty() ? 0 : ordered.get(0).floorNo(); + return new LaneView(laneCode, capacity, floor, ordered, occupied, corrupt, resident, guest, guests); + } + + private boolean blank(String value) { + return value == null || value.isBlank(); + } + + private record LaneView( + String laneCode, + int capacity, + int floorNo, + List spaces, + List occupied, + boolean corrupt, + String residentProject, + String guestProject, + List guestSpaces + ) { + } +} diff --git a/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyRequest.java b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyRequest.java new file mode 100644 index 0000000..5325040 --- /dev/null +++ b/fortucky-algorithm/src/main/java/com/ruoyi/algorithm/tidy/TidyRequest.java @@ -0,0 +1,28 @@ +package com.ruoyi.algorithm.tidy; + +import com.ruoyi.algorithm.model.SpaceState; +import com.ruoyi.algorithm.policy.SchedulingPolicy; + +import java.time.Instant; +import java.util.List; +import java.util.Set; + +public record TidyRequest( + List spaces, + List pendingOutbounds, + Instant now, + SchedulingPolicy policy, + Set commonProjectNos +) { + public TidyRequest { + spaces = List.copyOf(spaces); + pendingOutbounds = pendingOutbounds == null ? List.of() : List.copyOf(pendingOutbounds); + policy = policy == null ? SchedulingPolicy.ft546Defaults() : policy; + commonProjectNos = commonProjectNos == null ? Set.of("COMMON") : Set.copyOf(commonProjectNos); + } + + public TidyRequest(List spaces, List pendingOutbounds, + Instant now, SchedulingPolicy policy) { + this(spaces, pendingOutbounds, now, policy, Set.of("COMMON")); + } +} diff --git a/fortucky-algorithm/src/main/resources/db/sqlserver/diagnostics.sql b/fortucky-algorithm/src/main/resources/db/sqlserver/diagnostics.sql new file mode 100644 index 0000000..14a3530 --- /dev/null +++ b/fortucky-algorithm/src/main/resources/db/sqlserver/diagnostics.sql @@ -0,0 +1,224 @@ +/* Read-only validation queries for a SQL Server 2016 installation. */ +SET NOCOUNT ON; + +SELECT CAST(SERVERPROPERTY('ProductVersion') AS varchar(30)) AS product_version, + DB_NAME() AS database_name; + +SELECT o.type_desc, COUNT(*) AS object_count +FROM sys.objects o +JOIN sys.schemas s ON s.schema_id = o.schema_id +WHERE s.name = N'alg' AND o.type IN ('U', 'V', 'P') +GROUP BY o.type_desc +ORDER BY o.type_desc; + +SELECT installed.object_kind, installed.object_name +FROM ( + SELECT o.type_desc AS object_kind, o.name AS object_name + FROM sys.objects o + JOIN sys.schemas s ON s.schema_id = o.schema_id + WHERE s.name = N'alg' AND o.type IN ('U', 'V', 'P') + UNION ALL + SELECT 'INDEX' AS object_kind, i.name AS object_name + FROM sys.indexes i + JOIN sys.objects o ON o.object_id = i.object_id + JOIN sys.schemas s ON s.schema_id = o.schema_id + WHERE s.name = N'alg' AND i.name IS NOT NULL +) installed +ORDER BY installed.object_kind, installed.object_name; + +SELECT warehouse_id, + COUNT_BIG(*) AS excluded_from_algorithm_topology_count, + SUM(CASE WHEN group_coding_no IS NULL OR LTRIM(RTRIM(group_coding_no)) = '' + THEN 1 ELSE 0 END) AS missing_lane_code_count, + SUM(CASE WHEN TRY_CONVERT(int, group_coding) IS NULL + THEN 1 ELSE 0 END) AS invalid_depth_count +FROM dbo.bas_cargo_space +WHERE group_coding_no IS NULL OR LTRIM(RTRIM(group_coding_no)) = '' + OR TRY_CONVERT(int, group_coding) IS NULL +GROUP BY warehouse_id +ORDER BY warehouse_id; + +SELECT warehouse_id, + COUNT(*) AS space_state_count, + SUM(CASE WHEN space_status = 2 THEN 1 ELSE 0 END) AS full_space_count, + SUM(CASE WHEN inbound_available = 1 THEN 1 ELSE 0 END) AS inbound_available_count, + SUM(CASE WHEN pending_outbound = 1 THEN 1 ELSE 0 END) AS pending_outbound_space_count, + SUM(CASE WHEN has_gap = 1 THEN 1 ELSE 0 END) AS gap_space_count, + SUM(CASE WHEN tray_conflict = 1 OR project_conflict = 1 OR product_conflict = 1 THEN 1 ELSE 0 END) AS conflict_space_count +FROM alg.v_space_state +GROUP BY warehouse_id +ORDER BY warehouse_id; + +SELECT warehouse_id, COUNT(*) AS topology_count +FROM alg.space_topology +GROUP BY warehouse_id +ORDER BY warehouse_id; + +SELECT warehouse_id, + COUNT(*) AS inventory_detail_snapshot_count, + COUNT(DISTINCT space_id) AS inventory_space_snapshot_count, + MAX(synchronized_at) AS last_inventory_synchronized_at +FROM alg.inventory_item_snapshot +GROUP BY warehouse_id +ORDER BY warehouse_id; + +;WITH warehouse_floors AS ( + SELECT DISTINCT warehouse_id, the_floor AS floor_no + FROM dbo.bas_cargo_space +), role_counts AS ( + SELECT cargo.warehouse_id, cargo.the_floor AS floor_no, + SUM(CASE WHEN role.role = 'RELOCATION_BUFFER' THEN 1 ELSE 0 END) AS relocation_buffer_count, + SUM(CASE WHEN role.role = 'OUTBOUND_BUFFER' THEN 1 ELSE 0 END) AS outbound_buffer_count, + SUM(CASE WHEN role.role = 'PROTECTED_CORE' THEN 1 ELSE 0 END) AS protected_core_count + FROM dbo.bas_cargo_space cargo + LEFT JOIN alg.space_role role ON role.space_id = cargo.cargo_space_id + GROUP BY cargo.warehouse_id, cargo.the_floor +) +SELECT floors.warehouse_id, floors.floor_no, + ISNULL(counts.relocation_buffer_count, 0) AS relocation_buffer_count, + CAST(4 AS int) AS relocation_buffer_target, + CASE WHEN ISNULL(counts.relocation_buffer_count, 0) >= 4 THEN 0 + ELSE 4 - ISNULL(counts.relocation_buffer_count, 0) END AS relocation_buffer_shortage, + ISNULL(counts.outbound_buffer_count, 0) AS outbound_buffer_count, + ISNULL(counts.protected_core_count, 0) AS protected_core_count +FROM warehouse_floors floors +LEFT JOIN role_counts counts ON counts.warehouse_id = floors.warehouse_id + AND counts.floor_no = floors.floor_no +ORDER BY floors.warehouse_id, floors.floor_no; + +SELECT cargo.warehouse_id, cargo.the_floor AS floor_no, role.space_id, role.role, role.updated_at +FROM alg.space_role role +JOIN dbo.bas_cargo_space cargo ON cargo.cargo_space_id = role.space_id +WHERE role.role IN ('RELOCATION_BUFFER', 'OUTBOUND_BUFFER', 'PROTECTED_CORE') +ORDER BY cargo.warehouse_id, cargo.the_floor, role.role, role.space_id; + +SELECT warehouse_id, COUNT(*) AS lane_state_count, + SUM(CASE WHEN pending_outbound = 1 THEN 1 ELSE 0 END) AS pending_lane_count, + SUM(CASE WHEN has_gap = 1 THEN 1 ELSE 0 END) AS gap_lane_count +FROM alg.lane_state +GROUP BY warehouse_id +ORDER BY warehouse_id; + +SELECT 'bas_cargo_space' AS table_name, COUNT_BIG(*) AS row_count, + CHECKSUM_AGG(BINARY_CHECKSUM(cargo_space_id, warehouse_id, group_coding_no, group_coding, status, tray_code)) AS row_checksum +FROM dbo.bas_cargo_space +UNION ALL +SELECT 'bas_stock', COUNT_BIG(*), + CHECKSUM_AGG(BINARY_CHECKSUM(stock_id, cargo_space_id, tray_code, spare4, product_id, lot_no, in_date)) +FROM dbo.bas_stock +UNION ALL +SELECT 'mydo_job', COUNT_BIG(*), + CHECKSUM_AGG(BINARY_CHECKSUM(job_id, status, task_no, tray_code, cargo_space_id, target_cargo_space_id, in_or_out, warehouse_id)) +FROM dbo.mydo_job; + +;WITH pallet_details AS ( + SELECT cargo_space_id, + MIN(NULLIF(LTRIM(RTRIM(tray_code)), '')) AS tray_code, + MIN(NULLIF(LTRIM(RTRIM(spare4)), '')) AS project_no, + MIN(NULLIF(LTRIM(RTRIM(product_id)), '')) AS first_product_no, + MAX(NULLIF(LTRIM(RTRIM(product_id)), '')) AS last_product_no, + COUNT(DISTINCT NULLIF(LTRIM(RTRIM(product_id)), '')) AS product_count + FROM dbo.bas_stock + GROUP BY cargo_space_id +) +SELECT TOP 5 state.space_id, details.tray_code, details.project_no, + details.first_product_no, details.last_product_no, details.product_count +FROM pallet_details details +JOIN alg.v_space_state state ON state.space_id = details.cargo_space_id +WHERE details.product_count > 1 + AND state.space_status = '2' + AND state.stock_tray_count = 1 + AND state.stock_project_count = 1 + AND state.tray_conflict = 0 + AND state.project_conflict = 0 + AND state.pending_outbound = 0 + AND state.reserved = 0 + AND state.has_gap = 0 +ORDER BY state.space_id; + +SELECT space_id, warehouse_id, lane_code, depth, space_status, role, + tray_conflict, project_conflict, product_conflict, pending_outbound, reserved, has_gap, + inbound_available +FROM alg.v_space_state +WHERE tray_conflict = 1 OR project_conflict = 1 OR product_conflict = 1 + OR pending_outbound = 1 OR has_gap = 1 +ORDER BY warehouse_id, lane_code, depth; + +SELECT reservation_id, warehouse_id, lane_code, space_id, project_no, status, + created_at, released_at +FROM alg.reservation +ORDER BY created_at DESC; + +SELECT lock_id, request_id, warehouse_id, floor_no, status, created_at, released_at +FROM alg.deep_workflow_lock +ORDER BY created_at DESC; + +SELECT warehouse_id, lane_code, topology_dirty, reason_mask, change_count, + enqueued_at, last_changed_at +FROM alg.dirty_lane_queue +ORDER BY last_changed_at, warehouse_id, lane_code; + +SELECT workflow_id, request_id, stockout_detail_id, warehouse_id, source_stock_id, + selected_tray_code, source_space_id, lane_code, floor_no, exit_id, + status, current_step, total_steps, created_at, updated_at, completed_at +FROM alg.outbound_workflow +WHERE status <> 'COMPLETED' +ORDER BY created_at, workflow_id; + +SELECT step.workflow_id, step.assignment_id, step.phase, step.source_space_id, + step.target_space_id, step.workflow_step, step.workflow_total_steps, + step.depends_on_assignment_id, step.stock_id, step.tray_code, step.status, + step.wms_job_id, step.created_at, step.started_at, step.at_exit_at, step.completed_at +FROM alg.outbound_workflow_step step +JOIN alg.outbound_workflow workflow ON workflow.workflow_id = step.workflow_id +WHERE workflow.status <> 'COMPLETED' OR step.status <> 'COMPLETED' +ORDER BY step.workflow_id, step.workflow_step; + +SELECT mode.warehouse_id, mode.requested_enabled, mode.effective_state, + mode.status_reason, mode.mode_version, mode.updated_by, mode.updated_at +FROM alg.tidy_mode mode +ORDER BY mode.warehouse_id; + +SELECT queue.warehouse_id, queue.lane_code, queue.dirty_version, queue.queue_status, + queue.reason_mask, queue.change_count, queue.last_dirty_at, queue.claimed_version, + queue.claimed_by, queue.claimed_at, queue.lease_expires_at, queue.last_error +FROM alg.tidy_lane_queue queue +ORDER BY queue.last_dirty_at, queue.warehouse_id, queue.lane_code; + +SELECT workflow.workflow_id, workflow.warehouse_id, workflow.lane_code, workflow.origin, + workflow.candidate_type, workflow.source_space_id, workflow.target_space_id, + workflow.stock_id, workflow.tray_code, workflow.status, workflow.claimed_dirty_version, + workflow.vehicle_id, workflow.wcs_task_id, workflow.status_reason, + workflow.created_at, workflow.updated_at, workflow.dispatched_at, workflow.completed_at +FROM alg.tidy_workflow workflow +WHERE workflow.completed_at IS NULL + OR workflow.status IN ('PAUSED_RECOVERY', 'CANCELLED_RECONCILED') +ORDER BY workflow.created_at, workflow.workflow_id; + +SELECT step.workflow_id, step.step_id, step.step_no, step.source_space_id, + step.target_space_id, step.stock_id, step.tray_code, step.status, + step.wms_job_id, step.wcs_task_id, step.expected_event_stage, + step.created_at, step.started_at, step.completed_at +FROM alg.tidy_step step +JOIN alg.tidy_workflow workflow ON workflow.workflow_id = step.workflow_id +WHERE workflow.completed_at IS NULL OR step.completed_at IS NULL +ORDER BY step.workflow_id, step.step_no; + +SELECT lock.workflow_id, lock.warehouse_id, lock.resource_type, lock.resource_id, + lock.status, lock.locked_at, lock.released_at +FROM alg.tidy_space_lock lock +WHERE lock.status = 'ACTIVE' +ORDER BY lock.warehouse_id, lock.resource_type, lock.resource_id; + +SELECT event.workflow_id, event.step_id, event.wcs_task_id, event.event_stage, + COUNT(*) AS callback_count, MIN(event.received_at) AS first_received_at, + MAX(event.received_at) AS last_received_at +FROM alg.tidy_callback_event event +GROUP BY event.workflow_id, event.step_id, event.wcs_task_id, event.event_stage +HAVING COUNT(*) > 1 +ORDER BY event.workflow_id, event.step_id, event.event_stage; + +SELECT workflow.origin, workflow.status, COUNT(*) AS workflow_count +FROM alg.tidy_workflow workflow +GROUP BY workflow.origin, workflow.status +ORDER BY workflow.origin, workflow.status; diff --git a/fortucky-algorithm/src/main/resources/db/sqlserver/install.sql b/fortucky-algorithm/src/main/resources/db/sqlserver/install.sql new file mode 100644 index 0000000..1164263 --- /dev/null +++ b/fortucky-algorithm/src/main/resources/db/sqlserver/install.sql @@ -0,0 +1,1936 @@ +/* + FT546 algorithm read model for SQL Server 2016 RTM (13.0). + This script owns only schema alg. It never changes dbo.bas_cargo_space, + dbo.bas_stock, or dbo.mydo_job. +*/ +SET NOCOUNT ON; + +IF SCHEMA_ID(N'alg') IS NULL EXEC(N'CREATE SCHEMA alg'); +GO + +IF OBJECT_ID(N'alg.warehouse_policy', N'U') IS NULL +CREATE TABLE alg.warehouse_policy ( + warehouse_id varchar(80) NOT NULL PRIMARY KEY, + target_fill_rate decimal(9,4) NULL, + fifo_tolerance_hours int NULL, + updated_at datetime2 NOT NULL CONSTRAINT DF_alg_warehouse_policy_updated_at DEFAULT SYSUTCDATETIME() +); +GO + +IF OBJECT_ID(N'alg.project_policy', N'U') IS NULL +CREATE TABLE alg.project_policy ( + project_no varchar(255) NOT NULL PRIMARY KEY, + is_isolated bit NOT NULL CONSTRAINT DF_alg_project_policy_isolated DEFAULT 0, + is_common bit NOT NULL CONSTRAINT DF_alg_project_policy_common DEFAULT 0, + allow_mixed bit NOT NULL CONSTRAINT DF_alg_project_policy_mixed DEFAULT 0, + updated_at datetime2 NOT NULL CONSTRAINT DF_alg_project_policy_updated_at DEFAULT SYSUTCDATETIME() +); +GO + +IF OBJECT_ID(N'alg.space_role', N'U') IS NULL +CREATE TABLE alg.space_role ( + space_id varchar(80) NOT NULL PRIMARY KEY, + role varchar(40) NOT NULL, + updated_at datetime2 NOT NULL CONSTRAINT DF_alg_space_role_updated_at DEFAULT SYSUTCDATETIME(), + CONSTRAINT CK_alg_space_role_role CHECK (role IN ('STORAGE', 'RELOCATION_BUFFER', 'OUTBOUND_BUFFER', 'PROTECTED_CORE')) +); +GO + +IF OBJECT_ID(N'alg.space_topology', N'U') IS NULL +CREATE TABLE alg.space_topology ( + warehouse_id varchar(80) NOT NULL, + space_id varchar(80) NOT NULL CONSTRAINT PK_alg_space_topology PRIMARY KEY, + lane_code varchar(80) NOT NULL, + lane_depth int NOT NULL, + base_zone varchar(20) NOT NULL, + rebuilt_at datetime2 NOT NULL CONSTRAINT DF_alg_space_topology_rebuilt_at DEFAULT SYSUTCDATETIME(), + CONSTRAINT CK_alg_space_topology_base_zone CHECK (base_zone IN ('CACHE', 'RESERVE', 'MAIN', 'FLEX')) +); +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.space_topology') AND name = N'IX_alg_space_topology_warehouse_lane') +CREATE INDEX IX_alg_space_topology_warehouse_lane ON alg.space_topology(warehouse_id, lane_code); +GO + +IF OBJECT_ID(N'alg.inventory_item_snapshot', N'U') IS NULL +CREATE TABLE alg.inventory_item_snapshot ( + warehouse_id varchar(80) NOT NULL, + stock_id varchar(80) NOT NULL, + space_id varchar(80) NOT NULL, + tray_code varchar(255) NULL, + project_no varchar(255) NULL, + product_no varchar(255) NULL, + lot_no varchar(80) NULL, + inbound_time_raw varchar(80) NULL, + inbound_at datetime2 NULL, + quantity decimal(38,6) NULL, + out_quantity decimal(38,6) NULL, + synchronized_at datetime2 NOT NULL CONSTRAINT DF_alg_inventory_item_snapshot_sync DEFAULT SYSUTCDATETIME(), + CONSTRAINT PK_alg_inventory_item_snapshot PRIMARY KEY (warehouse_id, stock_id) +); +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.inventory_item_snapshot') AND name = N'IX_alg_inventory_item_snapshot_space') +CREATE INDEX IX_alg_inventory_item_snapshot_space ON alg.inventory_item_snapshot(warehouse_id, space_id); +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.inventory_item_snapshot') AND name = N'IX_alg_inventory_item_snapshot_tray') +CREATE INDEX IX_alg_inventory_item_snapshot_tray ON alg.inventory_item_snapshot(warehouse_id, tray_code) INCLUDE (space_id, project_no, product_no); +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.inventory_item_snapshot') AND name = N'IX_alg_inventory_item_snapshot_project_product') +CREATE INDEX IX_alg_inventory_item_snapshot_project_product ON alg.inventory_item_snapshot(warehouse_id, project_no, product_no) INCLUDE (space_id, tray_code, inbound_at); +GO + +IF OBJECT_ID(N'alg.space_inventory_summary', N'U') IS NULL +CREATE TABLE alg.space_inventory_summary ( + warehouse_id varchar(80) NOT NULL, + space_id varchar(80) NOT NULL, + stock_detail_count int NOT NULL, + stock_tray_count int NOT NULL, + stock_project_count int NOT NULL, + stock_product_count int NOT NULL, + synchronized_at datetime2 NOT NULL CONSTRAINT DF_alg_space_inventory_summary_sync DEFAULT SYSUTCDATETIME(), + CONSTRAINT PK_alg_space_inventory_summary PRIMARY KEY (warehouse_id, space_id) +); +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.space_inventory_summary') AND name = N'IX_alg_space_inventory_summary_space') +CREATE INDEX IX_alg_space_inventory_summary_space ON alg.space_inventory_summary(space_id, warehouse_id); +GO + +IF OBJECT_ID(N'alg.lane_state', N'U') IS NULL +CREATE TABLE alg.lane_state ( + warehouse_id varchar(80) NOT NULL, + lane_code varchar(80) NOT NULL, + space_count int NOT NULL CONSTRAINT DF_alg_lane_state_space_count DEFAULT 0, + occupied_count int NOT NULL CONSTRAINT DF_alg_lane_state_occupied_count DEFAULT 0, + available_count int NOT NULL CONSTRAINT DF_alg_lane_state_available_count DEFAULT 0, + pending_outbound bit NOT NULL CONSTRAINT DF_alg_lane_state_pending_outbound DEFAULT 0, + has_gap bit NOT NULL CONSTRAINT DF_alg_lane_state_has_gap DEFAULT 0, + semantic_fingerprint varbinary(32) NULL, + state_version rowversion NOT NULL, + rebuilt_at datetime2 NOT NULL CONSTRAINT DF_alg_lane_state_rebuilt_at DEFAULT SYSUTCDATETIME(), + CONSTRAINT PK_alg_lane_state PRIMARY KEY (warehouse_id, lane_code) +); +GO + +IF COL_LENGTH(N'alg.lane_state', N'semantic_fingerprint') IS NULL +ALTER TABLE alg.lane_state ADD semantic_fingerprint varbinary(32) NULL; +GO + +IF OBJECT_ID(N'alg.reservation', N'U') IS NULL +CREATE TABLE alg.reservation ( + reservation_id uniqueidentifier NOT NULL CONSTRAINT PK_alg_reservation PRIMARY KEY, + warehouse_id varchar(80) NOT NULL, + lane_code varchar(80) NOT NULL, + space_id varchar(80) NOT NULL, + project_no varchar(255) NULL, + status varchar(20) NOT NULL, + created_at datetime2 NOT NULL CONSTRAINT DF_alg_reservation_created_at DEFAULT SYSUTCDATETIME(), + released_at datetime2 NULL, + CONSTRAINT CK_alg_reservation_status CHECK (status IN ('ACTIVE', 'RELEASED', 'EXPIRED')) +); +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.reservation') AND name = N'UX_alg_reservation_active_space') +CREATE UNIQUE INDEX UX_alg_reservation_active_space ON alg.reservation(space_id) WHERE status = 'ACTIVE'; +GO + +IF OBJECT_ID(N'alg.deep_workflow_lock', N'U') IS NULL +CREATE TABLE alg.deep_workflow_lock ( + lock_id uniqueidentifier NOT NULL CONSTRAINT PK_alg_deep_workflow_lock PRIMARY KEY, + request_id varchar(80) NOT NULL, + warehouse_id varchar(80) NOT NULL, + floor_no int NOT NULL, + status varchar(20) NOT NULL, + created_at datetime2 NOT NULL CONSTRAINT DF_alg_deep_workflow_lock_created_at DEFAULT SYSUTCDATETIME(), + released_at datetime2 NULL, + CONSTRAINT CK_alg_deep_workflow_lock_status CHECK (status IN ('ACTIVE', 'RELEASED')) +); +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.deep_workflow_lock') AND name = N'UX_alg_deep_workflow_lock_active_floor') +CREATE UNIQUE INDEX UX_alg_deep_workflow_lock_active_floor +ON alg.deep_workflow_lock(warehouse_id, floor_no) WHERE status = 'ACTIVE'; +GO + +IF OBJECT_ID(N'alg.outbound_workflow', N'U') IS NULL +CREATE TABLE alg.outbound_workflow ( + workflow_id varchar(120) NOT NULL CONSTRAINT PK_alg_outbound_workflow PRIMARY KEY, + request_id varchar(80) NOT NULL, + stockout_detail_id varchar(80) NOT NULL, + warehouse_id varchar(80) NOT NULL, + source_stock_id varchar(80) NOT NULL, + selected_tray_code varchar(255) NOT NULL, + source_space_id varchar(80) NOT NULL, + lane_code varchar(80) NOT NULL, + floor_no int NOT NULL, + exit_id varchar(80) NOT NULL, + status varchar(20) NOT NULL, + current_step int NOT NULL CONSTRAINT DF_alg_outbound_workflow_current_step DEFAULT 0, + total_steps int NOT NULL, + created_at datetime2 NOT NULL CONSTRAINT DF_alg_outbound_workflow_created_at DEFAULT SYSUTCDATETIME(), + updated_at datetime2 NOT NULL CONSTRAINT DF_alg_outbound_workflow_updated_at DEFAULT SYSUTCDATETIME(), + completed_at datetime2 NULL, + CONSTRAINT CK_alg_outbound_workflow_status CHECK (status IN ('ACTIVE', 'COMPLETED', 'FAILED', 'CANCELLED')), + CONSTRAINT CK_alg_outbound_workflow_steps CHECK (total_steps > 0 AND current_step >= 0 AND current_step <= total_steps) +); +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.outbound_workflow') AND name = N'UX_alg_outbound_workflow_active_request') +CREATE UNIQUE INDEX UX_alg_outbound_workflow_active_request +ON alg.outbound_workflow(request_id, warehouse_id, floor_no) WHERE status = 'ACTIVE'; +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.outbound_workflow') AND name = N'IX_alg_outbound_workflow_stockout_detail') +CREATE INDEX IX_alg_outbound_workflow_stockout_detail +ON alg.outbound_workflow(stockout_detail_id, status) INCLUDE (workflow_id, warehouse_id, floor_no); +GO + +IF COL_LENGTH(N'alg.outbound_workflow', N'origin') IS NULL +ALTER TABLE alg.outbound_workflow ADD origin varchar(24) NOT NULL + CONSTRAINT DF_alg_outbound_workflow_origin DEFAULT 'OUTBOUND_RELOCATION'; +GO +IF NOT EXISTS ( + SELECT 1 FROM sys.check_constraints + WHERE parent_object_id = OBJECT_ID(N'alg.outbound_workflow') + AND name = N'CK_alg_outbound_workflow_origin') +ALTER TABLE alg.outbound_workflow WITH CHECK ADD CONSTRAINT CK_alg_outbound_workflow_origin + CHECK (origin = 'OUTBOUND_RELOCATION'); +GO + +IF OBJECT_ID(N'alg.outbound_workflow_step', N'U') IS NULL +CREATE TABLE alg.outbound_workflow_step ( + assignment_id varchar(120) NOT NULL CONSTRAINT PK_alg_outbound_workflow_step PRIMARY KEY, + workflow_id varchar(120) NOT NULL, + phase varchar(20) NOT NULL, + source_space_id varchar(80) NOT NULL, + target_space_id varchar(80) NULL, + workflow_step int NOT NULL, + workflow_total_steps int NOT NULL, + depends_on_assignment_id varchar(120) NULL, + stock_id varchar(80) NOT NULL, + tray_code varchar(255) NOT NULL, + status varchar(20) NOT NULL, + wms_job_id varchar(120) NULL, + created_at datetime2 NOT NULL CONSTRAINT DF_alg_outbound_workflow_step_created_at DEFAULT SYSUTCDATETIME(), + started_at datetime2 NULL, + at_exit_at datetime2 NULL, + completed_at datetime2 NULL, + CONSTRAINT FK_alg_outbound_workflow_step_workflow FOREIGN KEY (workflow_id) + REFERENCES alg.outbound_workflow(workflow_id), + CONSTRAINT FK_alg_outbound_workflow_step_dependency FOREIGN KEY (depends_on_assignment_id) + REFERENCES alg.outbound_workflow_step(assignment_id), + CONSTRAINT CK_alg_outbound_workflow_step_phase CHECK (phase IN ('MOVE_OUT', 'OUTBOUND', 'RESTORE')), + CONSTRAINT CK_alg_outbound_workflow_step_status CHECK (status IN ('PENDING', 'RUNNING', 'AT_EXIT', 'COMPLETED', 'FAILED')), + CONSTRAINT CK_alg_outbound_workflow_step_order CHECK ( + workflow_step > 0 AND workflow_total_steps > 0 AND workflow_step <= workflow_total_steps) +); +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.outbound_workflow_step') AND name = N'UX_alg_outbound_workflow_step_order') +CREATE UNIQUE INDEX UX_alg_outbound_workflow_step_order +ON alg.outbound_workflow_step(workflow_id, workflow_step); +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.outbound_workflow_step') AND name = N'UX_alg_outbound_workflow_step_wms_job') +CREATE UNIQUE INDEX UX_alg_outbound_workflow_step_wms_job +ON alg.outbound_workflow_step(wms_job_id) WHERE wms_job_id IS NOT NULL; +GO + +IF OBJECT_ID(N'alg.outbound_workflow_space', N'U') IS NULL +CREATE TABLE alg.outbound_workflow_space ( + workflow_id varchar(120) NOT NULL, + space_id varchar(80) NOT NULL, + status varchar(20) NOT NULL, + locked_at datetime2 NOT NULL CONSTRAINT DF_alg_outbound_workflow_space_locked_at DEFAULT SYSUTCDATETIME(), + released_at datetime2 NULL, + CONSTRAINT PK_alg_outbound_workflow_space PRIMARY KEY (workflow_id, space_id), + CONSTRAINT FK_alg_outbound_workflow_space_workflow FOREIGN KEY (workflow_id) + REFERENCES alg.outbound_workflow(workflow_id), + CONSTRAINT CK_alg_outbound_workflow_space_status CHECK (status IN ('ACTIVE', 'RELEASED')) +); +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.outbound_workflow_space') AND name = N'UX_alg_outbound_workflow_space_active') +CREATE UNIQUE INDEX UX_alg_outbound_workflow_space_active +ON alg.outbound_workflow_space(space_id) WHERE status = 'ACTIVE'; +GO + +IF OBJECT_ID(N'alg.dirty_lane_queue', N'U') IS NULL +CREATE TABLE alg.dirty_lane_queue ( + warehouse_id varchar(80) NOT NULL, + lane_code varchar(80) NOT NULL, + topology_dirty bit NOT NULL CONSTRAINT DF_alg_dirty_lane_queue_topology DEFAULT 0, + reason_mask int NOT NULL CONSTRAINT DF_alg_dirty_lane_queue_reason DEFAULT 0, + change_count bigint NOT NULL CONSTRAINT DF_alg_dirty_lane_queue_count DEFAULT 1, + enqueued_at datetime2 NOT NULL CONSTRAINT DF_alg_dirty_lane_queue_enqueued DEFAULT SYSUTCDATETIME(), + last_changed_at datetime2 NOT NULL CONSTRAINT DF_alg_dirty_lane_queue_changed DEFAULT SYSUTCDATETIME(), + CONSTRAINT PK_alg_dirty_lane_queue PRIMARY KEY (warehouse_id, lane_code) +); +GO + +IF OBJECT_ID(N'alg.tidy_mode', N'U') IS NULL +CREATE TABLE alg.tidy_mode ( + warehouse_id varchar(80) NOT NULL CONSTRAINT PK_alg_tidy_mode PRIMARY KEY, + requested_enabled bit NOT NULL CONSTRAINT DF_alg_tidy_mode_requested DEFAULT 0, + effective_state varchar(24) NOT NULL CONSTRAINT DF_alg_tidy_mode_state DEFAULT 'NORMAL', + status_reason varchar(255) NULL, + mode_version bigint NOT NULL CONSTRAINT DF_alg_tidy_mode_version DEFAULT 0, + updated_by varchar(80) NULL, + updated_at datetime2 NOT NULL CONSTRAINT DF_alg_tidy_mode_updated DEFAULT SYSUTCDATETIME(), + CONSTRAINT CK_alg_tidy_mode_effective_state CHECK ( + effective_state IN ('NORMAL', 'ENTERING_TIDY', 'TIDY_ACTIVE', 'EXITING_TIDY')) +); +GO + +IF OBJECT_ID(N'alg.tidy_lane_queue', N'U') IS NULL +CREATE TABLE alg.tidy_lane_queue ( + warehouse_id varchar(80) NOT NULL, + lane_code varchar(80) NOT NULL, + dirty_version bigint NOT NULL CONSTRAINT DF_alg_tidy_lane_queue_version DEFAULT 1, + queue_status varchar(20) NOT NULL CONSTRAINT DF_alg_tidy_lane_queue_status DEFAULT 'PENDING', + reason_mask int NOT NULL CONSTRAINT DF_alg_tidy_lane_queue_reason DEFAULT 0, + change_count bigint NOT NULL CONSTRAINT DF_alg_tidy_lane_queue_count DEFAULT 1, + last_dirty_at datetime2 NOT NULL CONSTRAINT DF_alg_tidy_lane_queue_dirty DEFAULT SYSUTCDATETIME(), + claim_token uniqueidentifier NULL, + claimed_version bigint NULL, + claimed_by varchar(120) NULL, + claimed_at datetime2 NULL, + lease_expires_at datetime2 NULL, + last_error varchar(2000) NULL, + CONSTRAINT PK_alg_tidy_lane_queue PRIMARY KEY (warehouse_id, lane_code), + CONSTRAINT CK_alg_tidy_lane_queue_status CHECK (queue_status IN ('PENDING', 'CLAIMED', 'COMPLETED')), + CONSTRAINT CK_alg_tidy_lane_queue_claim CHECK ( + (queue_status = 'CLAIMED' AND claim_token IS NOT NULL AND claimed_version IS NOT NULL + AND claimed_at IS NOT NULL AND lease_expires_at IS NOT NULL) + OR (queue_status <> 'CLAIMED' AND claim_token IS NULL AND claimed_version IS NULL + AND claimed_by IS NULL AND claimed_at IS NULL AND lease_expires_at IS NULL)) +); +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.tidy_lane_queue') AND name = N'IX_alg_tidy_lane_queue_claim') +CREATE INDEX IX_alg_tidy_lane_queue_claim +ON alg.tidy_lane_queue(queue_status, last_dirty_at, warehouse_id, lane_code) +INCLUDE (dirty_version, lease_expires_at); +GO + +IF OBJECT_ID(N'alg.tidy_workflow', N'U') IS NULL +CREATE TABLE alg.tidy_workflow ( + workflow_id varchar(120) NOT NULL CONSTRAINT PK_alg_tidy_workflow PRIMARY KEY, + warehouse_id varchar(80) NOT NULL, + lane_code varchar(80) NOT NULL, + origin varchar(24) NOT NULL, + candidate_type varchar(40) NOT NULL, + source_space_id varchar(80) NOT NULL, + target_space_id varchar(80) NOT NULL, + stock_id varchar(80) NOT NULL, + tray_code varchar(255) NOT NULL, + status varchar(24) NOT NULL, + claimed_dirty_version bigint NOT NULL, + lane_claim_token uniqueidentifier NOT NULL, + mode_version bigint NOT NULL, + vehicle_id varchar(80) NULL, + wcs_task_id varchar(120) NULL, + status_reason varchar(2000) NULL, + created_at datetime2 NOT NULL CONSTRAINT DF_alg_tidy_workflow_created DEFAULT SYSUTCDATETIME(), + updated_at datetime2 NOT NULL CONSTRAINT DF_alg_tidy_workflow_updated DEFAULT SYSUTCDATETIME(), + dispatched_at datetime2 NULL, + completed_at datetime2 NULL, + CONSTRAINT CK_alg_tidy_workflow_origin CHECK (origin IN ('AUTO_TIDY', 'MANUAL_TIDY')), + CONSTRAINT CK_alg_tidy_workflow_status CHECK (status IN ( + 'CLAIMED', 'WAITING_DISPATCH', 'DISPATCHED', 'RUNNING', 'PAUSED_RECOVERY', + 'COMPLETED', 'CANCELLED_RECONCILED')), + CONSTRAINT CK_alg_tidy_workflow_spaces CHECK (source_space_id <> target_space_id) +); +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.tidy_workflow') AND name = N'UX_alg_tidy_workflow_active_auto') +/* Automatic tidy is intentionally a global singleton across all warehouses. */ +CREATE UNIQUE INDEX UX_alg_tidy_workflow_active_auto +ON alg.tidy_workflow(origin) +WHERE origin = 'AUTO_TIDY' AND completed_at IS NULL; +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.tidy_workflow') AND name = N'UX_alg_tidy_workflow_wcs_task') +CREATE UNIQUE INDEX UX_alg_tidy_workflow_wcs_task +ON alg.tidy_workflow(wcs_task_id) WHERE wcs_task_id IS NOT NULL; +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.tidy_workflow') AND name = N'IX_alg_tidy_workflow_active') +CREATE INDEX IX_alg_tidy_workflow_active +ON alg.tidy_workflow(status, origin, warehouse_id, created_at) +INCLUDE (workflow_id, lane_code, vehicle_id, wcs_task_id); +GO + +IF OBJECT_ID(N'alg.tidy_step', N'U') IS NULL +CREATE TABLE alg.tidy_step ( + step_id varchar(120) NOT NULL CONSTRAINT PK_alg_tidy_step PRIMARY KEY, + workflow_id varchar(120) NOT NULL, + step_no int NOT NULL, + source_space_id varchar(80) NOT NULL, + target_space_id varchar(80) NOT NULL, + stock_id varchar(80) NOT NULL, + tray_code varchar(255) NOT NULL, + status varchar(24) NOT NULL, + wms_job_id varchar(120) NULL, + wcs_task_id varchar(120) NULL, + expected_event_stage varchar(40) NULL, + created_at datetime2 NOT NULL CONSTRAINT DF_alg_tidy_step_created DEFAULT SYSUTCDATETIME(), + started_at datetime2 NULL, + completed_at datetime2 NULL, + CONSTRAINT FK_alg_tidy_step_workflow FOREIGN KEY (workflow_id) + REFERENCES alg.tidy_workflow(workflow_id), + CONSTRAINT CK_alg_tidy_step_no CHECK (step_no > 0), + CONSTRAINT CK_alg_tidy_step_status CHECK (status IN ( + 'PENDING', 'DISPATCHED', 'RUNNING', 'PAUSED_RECOVERY', 'COMPLETED', 'CANCELLED_RECONCILED')) +); +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.tidy_step') AND name = N'UX_alg_tidy_step_order') +CREATE UNIQUE INDEX UX_alg_tidy_step_order ON alg.tidy_step(workflow_id, step_no); +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.tidy_step') AND name = N'UX_alg_tidy_step_workflow_key') +CREATE UNIQUE INDEX UX_alg_tidy_step_workflow_key ON alg.tidy_step(step_id, workflow_id); +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.tidy_step') AND name = N'UX_alg_tidy_step_wms_job') +CREATE UNIQUE INDEX UX_alg_tidy_step_wms_job ON alg.tidy_step(wms_job_id) WHERE wms_job_id IS NOT NULL; +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.tidy_step') AND name = N'UX_alg_tidy_step_wcs_task') +CREATE UNIQUE INDEX UX_alg_tidy_step_wcs_task ON alg.tidy_step(wcs_task_id) WHERE wcs_task_id IS NOT NULL; +GO + +IF OBJECT_ID(N'alg.tidy_space_lock', N'U') IS NULL +CREATE TABLE alg.tidy_space_lock ( + lock_id uniqueidentifier NOT NULL CONSTRAINT PK_alg_tidy_space_lock PRIMARY KEY, + workflow_id varchar(120) NOT NULL, + warehouse_id varchar(80) NOT NULL, + resource_type varchar(8) NOT NULL, + resource_id varchar(120) NOT NULL, + status varchar(20) NOT NULL CONSTRAINT DF_alg_tidy_space_lock_status DEFAULT 'ACTIVE', + locked_at datetime2 NOT NULL CONSTRAINT DF_alg_tidy_space_lock_locked DEFAULT SYSUTCDATETIME(), + released_at datetime2 NULL, + CONSTRAINT FK_alg_tidy_space_lock_workflow FOREIGN KEY (workflow_id) + REFERENCES alg.tidy_workflow(workflow_id), + CONSTRAINT CK_alg_tidy_space_lock_resource_type CHECK (resource_type IN ('SPACE', 'LANE', 'FLOOR')), + CONSTRAINT CK_alg_tidy_space_lock_status CHECK (status IN ('ACTIVE', 'RELEASED')) +); +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.tidy_space_lock') AND name = N'UX_alg_tidy_space_lock_active') +CREATE UNIQUE INDEX UX_alg_tidy_space_lock_active +ON alg.tidy_space_lock(warehouse_id, resource_type, resource_id) WHERE status = 'ACTIVE'; +GO + +IF OBJECT_ID(N'alg.tidy_callback_event', N'U') IS NULL +CREATE TABLE alg.tidy_callback_event ( + callback_event_id uniqueidentifier NOT NULL CONSTRAINT PK_alg_tidy_callback_event PRIMARY KEY, + workflow_id varchar(120) NOT NULL, + step_id varchar(120) NOT NULL, + wcs_task_id varchar(120) NOT NULL, + event_stage varchar(40) NOT NULL, + result_code varchar(40) NOT NULL, + result_message varchar(2000) NULL, + received_at datetime2 NOT NULL CONSTRAINT DF_alg_tidy_callback_event_received DEFAULT SYSUTCDATETIME(), + CONSTRAINT FK_alg_tidy_callback_event_workflow FOREIGN KEY (workflow_id) + REFERENCES alg.tidy_workflow(workflow_id), + CONSTRAINT FK_alg_tidy_callback_event_step FOREIGN KEY (step_id) + REFERENCES alg.tidy_step(step_id), + CONSTRAINT FK_alg_tidy_callback_event_step_workflow FOREIGN KEY (step_id, workflow_id) + REFERENCES alg.tidy_step(step_id, workflow_id) +); +GO +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(N'alg.tidy_callback_event') AND name = N'UX_alg_tidy_callback_event_key') +CREATE UNIQUE INDEX UX_alg_tidy_callback_event_key +ON alg.tidy_callback_event(workflow_id, step_id, wcs_task_id, event_stage); +GO + +IF OBJECT_ID(N'alg.decision_log', N'U') IS NULL +CREATE TABLE alg.decision_log ( + decision_id uniqueidentifier NOT NULL CONSTRAINT PK_alg_decision_log PRIMARY KEY, + warehouse_id varchar(80) NULL, + decision_type varchar(40) NOT NULL, + input_version binary(8) NULL, + result_code varchar(80) NULL, + reason varchar(2000) NULL, + created_at datetime2 NOT NULL CONSTRAINT DF_alg_decision_log_created_at DEFAULT SYSUTCDATETIME() +); +GO + +IF OBJECT_ID(N'alg.usp_rebuild_space_topology', N'P') IS NOT NULL DROP PROCEDURE alg.usp_rebuild_space_topology; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_rebuild_space_topology + @warehouse_id varchar(80) = NULL +AS +BEGIN + SET NOCOUNT ON; + ;WITH lane_topology AS ( + SELECT warehouse_id, group_coding_no AS lane_code, + COUNT(*) AS lane_depth, + MAX(the_column) AS column_no, + MIN(the_platoon) AS row_no, + MIN(the_floor) AS floor_no, + MIN(cargo_space_id) AS stable_id + FROM dbo.bas_cargo_space + WHERE NULLIF(LTRIM(RTRIM(group_coding_no)), '''') IS NOT NULL + AND TRY_CONVERT(int, group_coding) IS NOT NULL + AND (@warehouse_id IS NULL OR warehouse_id = @warehouse_id) + GROUP BY warehouse_id, group_coding_no + ), ranked_lanes AS ( + SELECT lane_topology.*, + CASE WHEN lane_depth = 1 THEN ROW_NUMBER() OVER ( + PARTITION BY warehouse_id + ORDER BY CASE WHEN lane_depth = 1 THEN 0 ELSE 1 END, + column_no DESC, row_no ASC, floor_no ASC, stable_id ASC + ) END AS single_depth_rank + FROM lane_topology + ), source AS ( + SELECT c.warehouse_id, c.cargo_space_id AS space_id, c.group_coding_no AS lane_code, + ranked_lanes.lane_depth, + CASE WHEN ranked_lanes.lane_depth = 1 AND ranked_lanes.single_depth_rank <= 80 THEN ''CACHE'' + WHEN ranked_lanes.lane_depth = 1 AND ranked_lanes.single_depth_rank <= 133 THEN ''RESERVE'' + WHEN ranked_lanes.lane_depth = 5 THEN ''MAIN'' + ELSE ''FLEX'' END AS base_zone + FROM dbo.bas_cargo_space c + JOIN ranked_lanes ON ranked_lanes.warehouse_id = c.warehouse_id + AND ranked_lanes.lane_code = c.group_coding_no + WHERE NULLIF(LTRIM(RTRIM(c.group_coding_no)), '''') IS NOT NULL + AND TRY_CONVERT(int, c.group_coding) IS NOT NULL + AND (@warehouse_id IS NULL OR c.warehouse_id = @warehouse_id) + ) + MERGE alg.space_topology AS target + USING source ON source.space_id = target.space_id + WHEN MATCHED AND (target.warehouse_id <> source.warehouse_id OR target.lane_code <> source.lane_code + OR target.lane_depth <> source.lane_depth OR target.base_zone <> source.base_zone) + THEN UPDATE SET warehouse_id = source.warehouse_id, lane_code = source.lane_code, + lane_depth = source.lane_depth, base_zone = source.base_zone, + rebuilt_at = SYSUTCDATETIME() + WHEN NOT MATCHED BY TARGET THEN + INSERT (warehouse_id, space_id, lane_code, lane_depth, base_zone) + VALUES (source.warehouse_id, source.space_id, source.lane_code, source.lane_depth, source.base_zone) + WHEN NOT MATCHED BY SOURCE AND (@warehouse_id IS NULL OR target.warehouse_id = @warehouse_id) + THEN DELETE; +END;'); +GO + +IF OBJECT_ID(N'alg.usp_sync_inventory_snapshot', N'P') IS NOT NULL DROP PROCEDURE alg.usp_sync_inventory_snapshot; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_sync_inventory_snapshot + @warehouse_id varchar(80) = NULL +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT ON; + BEGIN TRANSACTION; + + DELETE summary + FROM alg.space_inventory_summary summary + WHERE @warehouse_id IS NULL OR summary.warehouse_id = @warehouse_id; + + DELETE item + FROM alg.inventory_item_snapshot item + WHERE @warehouse_id IS NULL OR item.warehouse_id = @warehouse_id; + + INSERT INTO alg.inventory_item_snapshot ( + warehouse_id, stock_id, space_id, tray_code, project_no, product_no, lot_no, + inbound_time_raw, inbound_at, quantity, out_quantity, synchronized_at) + SELECT space.warehouse_id, stock.stock_id, stock.cargo_space_id, stock.tray_code, + stock.spare4, stock.product_id, stock.lot_no, CONVERT(varchar(80), stock.in_date), + TRY_CONVERT(datetime2, stock.in_date), stock.quantity, stock.out_quantity, SYSUTCDATETIME() + FROM dbo.bas_stock stock + JOIN dbo.bas_cargo_space space ON space.cargo_space_id = stock.cargo_space_id + WHERE @warehouse_id IS NULL OR space.warehouse_id = @warehouse_id; + + INSERT INTO alg.space_inventory_summary ( + warehouse_id, space_id, stock_detail_count, stock_tray_count, + stock_project_count, stock_product_count, synchronized_at) + SELECT item.warehouse_id, item.space_id, COUNT(*), + COUNT(DISTINCT NULLIF(LTRIM(RTRIM(item.tray_code)), '''')), + COUNT(DISTINCT NULLIF(LTRIM(RTRIM(item.project_no)), '''')), + COUNT(DISTINCT NULLIF(LTRIM(RTRIM(item.product_no)), '''')), + SYSUTCDATETIME() + FROM alg.inventory_item_snapshot item + WHERE @warehouse_id IS NULL OR item.warehouse_id = @warehouse_id + GROUP BY item.warehouse_id, item.space_id; + + COMMIT TRANSACTION; +END;'); +GO + +IF OBJECT_ID(N'alg.usp_apply_space_role', N'P') IS NOT NULL DROP PROCEDURE alg.usp_apply_space_role; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_apply_space_role + @warehouse_id varchar(80), + @space_id varchar(80), + @role varchar(40) +AS +BEGIN + SET NOCOUNT ON; + IF @role NOT IN (''STORAGE'', ''RELOCATION_BUFFER'', ''OUTBOUND_BUFFER'', ''PROTECTED_CORE'') + BEGIN + SELECT CONVERT(bit, 0) AS applied, CAST(''INVALID_ROLE'' AS varchar(80)) AS reason; + RETURN; + END; + + DECLARE @warehouse_count int, @space_status varchar(5), @locked varchar(5), + @tray_code varchar(255), @stock_count int, @reservation_count int; + SELECT @warehouse_count = COUNT(*) + FROM dbo.bas_cargo_space WITH (UPDLOCK, HOLDLOCK) + WHERE warehouse_id = @warehouse_id; + IF ISNULL(@warehouse_count, 0) = 0 + BEGIN + SELECT CONVERT(bit, 0) AS applied, CAST(''WAREHOUSE_NOT_FOUND'' AS varchar(80)) AS reason; + RETURN; + END; + + SELECT @space_status = status, @locked = locked, @tray_code = tray_code + FROM dbo.bas_cargo_space WITH (UPDLOCK, HOLDLOCK) + WHERE warehouse_id = @warehouse_id AND cargo_space_id = @space_id; + IF @space_status IS NULL + BEGIN + SELECT CONVERT(bit, 0) AS applied, CAST(''SPACE_NOT_FOUND'' AS varchar(80)) AS reason; + RETURN; + END; + + SELECT @stock_count = COUNT(*) FROM dbo.bas_stock WITH (UPDLOCK, HOLDLOCK) + WHERE cargo_space_id = @space_id; + SELECT @reservation_count = COUNT(*) FROM alg.reservation WITH (UPDLOCK, HOLDLOCK) + WHERE space_id = @space_id AND status = ''ACTIVE''; + + IF @role <> ''STORAGE'' AND ( + @space_status <> ''1'' OR + (NULLIF(LTRIM(RTRIM(@locked)), '''') IS NOT NULL AND LTRIM(RTRIM(@locked)) NOT IN (''0'', ''N'')) OR + NULLIF(LTRIM(RTRIM(@tray_code)), '''') IS NOT NULL OR + ISNULL(@stock_count, 0) <> 0 OR ISNULL(@reservation_count, 0) <> 0) + BEGIN + SELECT CONVERT(bit, 0) AS applied, CAST(''TARGET_NOT_EMPTY_OR_RESERVED'' AS varchar(80)) AS reason; + RETURN; + END; + + MERGE alg.space_role WITH (HOLDLOCK) AS target + USING (SELECT @space_id AS space_id, @role AS role) AS source + ON source.space_id = target.space_id + WHEN MATCHED THEN UPDATE SET role = source.role, updated_at = SYSUTCDATETIME() + WHEN NOT MATCHED THEN INSERT (space_id, role) VALUES (source.space_id, source.role); + + SELECT CONVERT(bit, 1) AS applied, CAST(NULL AS varchar(80)) AS reason; +END;'); +GO + +IF OBJECT_ID(N'alg.v_inventory_item', N'V') IS NOT NULL DROP VIEW alg.v_inventory_item; +GO +EXEC(N' +CREATE VIEW alg.v_inventory_item AS +SELECT stock_id, space_id, tray_code, project_no, product_no, lot_no, + inbound_time_raw, inbound_at, quantity, out_quantity +FROM alg.inventory_item_snapshot;'); +GO + +IF OBJECT_ID(N'alg.v_active_job', N'V') IS NOT NULL DROP VIEW alg.v_active_job; +GO +EXEC(N' +CREATE VIEW alg.v_active_job AS +WITH tray_candidates AS ( + SELECT j.job_id, + COUNT(DISTINCT s.space_id) AS space_count, + MIN(s.space_id) AS cargo_space_id, + COUNT(DISTINCT NULLIF(LTRIM(RTRIM(s.project_no)), '''')) AS project_count, + MIN(NULLIF(LTRIM(RTRIM(s.project_no)), '''')) AS project_no, + COUNT(DISTINCT NULLIF(LTRIM(RTRIM(s.product_no)), '''')) AS product_count, + MIN(NULLIF(LTRIM(RTRIM(s.product_no)), '''')) AS product_no + FROM dbo.mydo_job j + JOIN alg.inventory_item_snapshot s ON s.warehouse_id = j.warehouse_id + AND s.tray_code = NULLIF(LTRIM(RTRIM(j.tray_code)), '''') + GROUP BY j.job_id +), resolved_jobs AS ( + SELECT j.job_id, j.task_no, j.tray_code, j.target_cargo_space_id, j.warehouse_id, + j.status, j.in_or_out, j.create_time AS create_time_raw, + COALESCE(source_space.cargo_space_id, + CASE WHEN tray_candidates.space_count = 1 THEN tray_candidates.cargo_space_id END) AS source_space_id, + CASE WHEN source_space.cargo_space_id IS NOT NULL THEN ''EXPLICIT'' + WHEN tray_candidates.space_count = 1 THEN ''TRAY'' + WHEN tray_candidates.space_count > 1 THEN ''AMBIGUOUS_TRAY'' + ELSE ''UNRESOLVED'' END AS source_resolution + FROM dbo.mydo_job j + LEFT JOIN dbo.bas_cargo_space source_space + ON source_space.cargo_space_id = NULLIF(LTRIM(RTRIM(j.cargo_space_id)), '''') + AND source_space.warehouse_id = j.warehouse_id + LEFT JOIN tray_candidates ON tray_candidates.job_id = j.job_id + WHERE j.finish_time IS NULL OR LTRIM(RTRIM(j.finish_time)) = '''' +), source_scope AS ( + SELECT resolved_jobs.job_id, + COUNT(DISTINCT NULLIF(LTRIM(RTRIM(stock.project_no)), '''')) AS project_count, + MIN(NULLIF(LTRIM(RTRIM(stock.project_no)), '''')) AS project_no, + COUNT(DISTINCT NULLIF(LTRIM(RTRIM(stock.product_no)), '''')) AS product_count, + MIN(NULLIF(LTRIM(RTRIM(stock.product_no)), '''')) AS product_no + FROM resolved_jobs + JOIN alg.inventory_item_snapshot stock ON stock.warehouse_id = resolved_jobs.warehouse_id + AND stock.space_id = resolved_jobs.source_space_id + GROUP BY resolved_jobs.job_id +) +SELECT resolved_jobs.job_id, resolved_jobs.task_no, resolved_jobs.tray_code, + CASE WHEN resolved_jobs.source_space_id IS NOT NULL + THEN CASE WHEN source_scope.project_count = 1 THEN source_scope.project_no END + ELSE CASE WHEN tray_candidates.project_count = 1 THEN tray_candidates.project_no END END AS project_no, + CASE WHEN resolved_jobs.source_space_id IS NOT NULL + THEN CASE WHEN source_scope.product_count = 1 THEN source_scope.product_no END + ELSE CASE WHEN tray_candidates.product_count = 1 THEN tray_candidates.product_no END END AS product_no, + resolved_jobs.source_space_id, resolved_jobs.target_cargo_space_id, resolved_jobs.warehouse_id, + resolved_jobs.status, resolved_jobs.in_or_out, resolved_jobs.create_time_raw, + resolved_space.group_coding_no AS source_lane_code, resolved_jobs.source_resolution +FROM resolved_jobs +LEFT JOIN tray_candidates ON tray_candidates.job_id = resolved_jobs.job_id +LEFT JOIN source_scope ON source_scope.job_id = resolved_jobs.job_id +LEFT JOIN dbo.bas_cargo_space resolved_space ON resolved_space.cargo_space_id = resolved_jobs.source_space_id;'); +GO + +IF OBJECT_ID(N'alg.v_space_state', N'V') IS NOT NULL DROP VIEW alg.v_space_state; +GO +EXEC(N' +CREATE VIEW alg.v_space_state AS +WITH outbound_lanes AS ( + SELECT DISTINCT warehouse_id, source_lane_code AS lane_code + FROM alg.v_active_job + WHERE in_or_out >= 20 AND source_lane_code IS NOT NULL +), lane_gaps AS ( + SELECT DISTINCT inner_space.warehouse_id, inner_space.group_coding_no AS lane_code + FROM dbo.bas_cargo_space inner_space + JOIN dbo.bas_cargo_space outer_space + ON outer_space.warehouse_id = inner_space.warehouse_id + AND outer_space.group_coding_no = inner_space.group_coding_no + AND TRY_CONVERT(int, outer_space.group_coding) > TRY_CONVERT(int, inner_space.group_coding) + WHERE TRY_CONVERT(int, inner_space.group_coding) IS NOT NULL + AND TRY_CONVERT(int, outer_space.group_coding) IS NOT NULL + AND NULLIF(LTRIM(RTRIM(inner_space.tray_code)), '''') IS NULL + AND NOT EXISTS ( + SELECT 1 FROM alg.inventory_item_snapshot inner_stock + WHERE inner_stock.warehouse_id = inner_space.warehouse_id + AND inner_stock.space_id = inner_space.cargo_space_id + ) + AND ( + NULLIF(LTRIM(RTRIM(outer_space.tray_code)), '''') IS NOT NULL + OR EXISTS ( + SELECT 1 FROM alg.inventory_item_snapshot outer_stock + WHERE outer_stock.warehouse_id = outer_space.warehouse_id + AND outer_stock.space_id = outer_space.cargo_space_id + ) + ) +) +SELECT c.cargo_space_id AS space_id, + c.warehouse_id, + c.group_coding_no AS lane_code, + c.cargo_area_id AS area_id, + CASE + WHEN ISNULL(role.role, ''STORAGE'') IN (''RELOCATION_BUFFER'', ''OUTBOUND_BUFFER'') THEN ''CACHE'' + WHEN ISNULL(role.role, ''STORAGE'') = ''PROTECTED_CORE'' THEN ''RESERVE'' + ELSE topology.base_zone + END AS zone_code, + c.roadway_id, + c.cargo_space_name AS display_name, + c.the_platoon AS platoon, + c.the_column AS column_no, + c.the_floor AS floor_no, + c.group_coding AS depth_raw, + TRY_CONVERT(int, c.group_coding) AS depth, + c.status AS space_status, + c.locked, + c.tray_code AS space_tray_code, + ISNULL(role.role, ''STORAGE'') AS role, + ISNULL(stock.stock_detail_count, 0) AS stock_detail_count, + ISNULL(stock.stock_tray_count, 0) AS stock_tray_count, + ISNULL(stock.stock_project_count, 0) AS stock_project_count, + ISNULL(stock.stock_product_count, 0) AS stock_product_count, + CONVERT(bit, CASE WHEN ISNULL(stock.stock_tray_count, 0) > 1 THEN 1 ELSE 0 END) AS tray_conflict, + CONVERT(bit, CASE WHEN ISNULL(stock.stock_project_count, 0) > 1 THEN 1 ELSE 0 END) AS project_conflict, + CONVERT(bit, 0) AS product_conflict, + CONVERT(bit, CASE WHEN outbound_lanes.lane_code IS NULL THEN 0 ELSE 1 END) AS pending_outbound, + active_reservations.reservation_id, + CONVERT(bit, CASE WHEN active_reservations.reservation_id IS NULL THEN 0 ELSE 1 END) AS reserved, + CONVERT(bit, CASE WHEN lane_gaps.lane_code IS NULL THEN 0 ELSE 1 END) AS has_gap, + CONVERT(bit, CASE + WHEN c.status IS NULL OR c.status <> ''1'' THEN 0 + WHEN NULLIF(LTRIM(RTRIM(c.locked)), '''') IS NOT NULL AND LTRIM(RTRIM(c.locked)) NOT IN (''0'', ''N'') THEN 0 + WHEN NULLIF(LTRIM(RTRIM(c.tray_code)), '''') IS NOT NULL THEN 0 + WHEN ISNULL(stock.stock_detail_count, 0) <> 0 THEN 0 + WHEN TRY_CONVERT(int, c.group_coding) IS NULL THEN 0 + WHEN ISNULL(role.role, ''STORAGE'') <> ''STORAGE'' THEN 0 + WHEN outbound_lanes.lane_code IS NOT NULL THEN 0 + WHEN active_reservations.reservation_id IS NOT NULL THEN 0 + WHEN lane_gaps.lane_code IS NOT NULL THEN 0 + WHEN EXISTS ( + SELECT 1 + FROM dbo.bas_cargo_space inner_candidate + LEFT JOIN alg.space_inventory_summary inner_stock + ON inner_stock.warehouse_id = inner_candidate.warehouse_id + AND inner_stock.space_id = inner_candidate.cargo_space_id + WHERE inner_candidate.warehouse_id = c.warehouse_id + AND inner_candidate.group_coding_no = c.group_coding_no + AND TRY_CONVERT(int, inner_candidate.group_coding) < TRY_CONVERT(int, c.group_coding) + AND inner_candidate.status = ''1'' + AND NULLIF(LTRIM(RTRIM(inner_candidate.tray_code)), '''') IS NULL + AND inner_stock.space_id IS NULL + ) THEN 0 + ELSE 1 END) AS inbound_available +FROM dbo.bas_cargo_space c +JOIN alg.space_topology topology ON topology.space_id = c.cargo_space_id +LEFT JOIN alg.space_inventory_summary stock ON stock.warehouse_id = c.warehouse_id + AND stock.space_id = c.cargo_space_id +LEFT JOIN alg.space_role role ON role.space_id = c.cargo_space_id +LEFT JOIN outbound_lanes ON outbound_lanes.warehouse_id = c.warehouse_id AND outbound_lanes.lane_code = c.group_coding_no +LEFT JOIN alg.reservation active_reservations ON active_reservations.space_id = c.cargo_space_id AND active_reservations.status = ''ACTIVE'' +LEFT JOIN lane_gaps ON lane_gaps.warehouse_id = c.warehouse_id AND lane_gaps.lane_code = c.group_coding_no;'); +GO + +IF OBJECT_ID(N'alg.usp_compute_lane_semantic_fingerprint', N'P') IS NOT NULL DROP PROCEDURE alg.usp_compute_lane_semantic_fingerprint; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_compute_lane_semantic_fingerprint + @warehouse_id varchar(80), + @lane_code varchar(80), + @semantic_fingerprint varbinary(32) OUTPUT, + @inventory_source varchar(20) = ''LIVE'' +AS +BEGIN + SET NOCOUNT ON; + DECLARE @payload nvarchar(max); + + CREATE TABLE #fingerprint_inventory ( + stock_id varchar(80) NOT NULL, + space_id varchar(80) NOT NULL, + tray_code varchar(255) NULL, + project_no varchar(255) NULL, + product_no varchar(255) NULL, + lot_no varchar(80) NULL, + inbound_time varchar(80) NULL, + quantity decimal(38,6) NULL, + out_quantity decimal(38,6) NULL + ); + + IF @inventory_source = ''SNAPSHOT'' + BEGIN + INSERT INTO #fingerprint_inventory ( + stock_id, space_id, tray_code, project_no, product_no, lot_no, + inbound_time, quantity, out_quantity) + SELECT stock.stock_id, stock.space_id, stock.tray_code, stock.project_no, + stock.product_no, stock.lot_no, stock.inbound_time_raw, + CONVERT(decimal(38,6), stock.quantity), CONVERT(decimal(38,6), stock.out_quantity) + FROM alg.inventory_item_snapshot stock + JOIN dbo.bas_cargo_space cargo ON cargo.cargo_space_id = stock.space_id + AND cargo.warehouse_id = stock.warehouse_id + WHERE cargo.warehouse_id = @warehouse_id AND cargo.group_coding_no = @lane_code; + END + ELSE IF @inventory_source = ''LIVE'' + BEGIN + INSERT INTO #fingerprint_inventory ( + stock_id, space_id, tray_code, project_no, product_no, lot_no, + inbound_time, quantity, out_quantity) + SELECT stock.stock_id, stock.cargo_space_id, stock.tray_code, stock.spare4, + stock.product_id, stock.lot_no, CONVERT(varchar(80), stock.in_date), + CONVERT(decimal(38,6), stock.quantity), CONVERT(decimal(38,6), stock.out_quantity) + FROM dbo.bas_stock stock + JOIN dbo.bas_cargo_space cargo ON cargo.cargo_space_id = stock.cargo_space_id + WHERE cargo.warehouse_id = @warehouse_id AND cargo.group_coding_no = @lane_code; + END + ELSE + BEGIN + THROW 50001, ''Unsupported inventory fingerprint source'', 1; + END; + + SELECT @payload = ISNULL(CONVERT(nvarchar(max), ( + SELECT cargo.cargo_space_id AS [@space_id], cargo.status AS [@status], + cargo.locked AS [@locked], cargo.tray_code AS [@tray_code], + cargo.group_coding AS [@depth], cargo.the_platoon AS [@platoon], + cargo.the_column AS [@column], cargo.the_floor AS [@floor], + topology.lane_depth AS [@lane_depth], topology.base_zone AS [@base_zone], + ISNULL(role.role, ''STORAGE'') AS [@role] + FROM dbo.bas_cargo_space cargo + LEFT JOIN alg.space_topology topology ON topology.space_id = cargo.cargo_space_id + LEFT JOIN alg.space_role role ON role.space_id = cargo.cargo_space_id + WHERE cargo.warehouse_id = @warehouse_id AND cargo.group_coding_no = @lane_code + ORDER BY TRY_CONVERT(int, cargo.group_coding), cargo.cargo_space_id + FOR XML PATH(''space''), ROOT(''spaces''), TYPE + )), N''''); + + SET @payload = @payload + N''|INVENTORY|'' + ISNULL(CONVERT(nvarchar(max), ( + SELECT stock.stock_id AS [@stock_id], stock.space_id AS [@space_id], + stock.tray_code AS [@tray_code], stock.project_no AS [@project_no], + stock.product_no AS [@product_no], stock.lot_no AS [@lot_no], + stock.inbound_time AS [@inbound_time], + stock.quantity AS [@quantity], stock.out_quantity AS [@out_quantity] + FROM #fingerprint_inventory stock + ORDER BY stock.space_id, stock.stock_id + FOR XML PATH(''item''), ROOT(''inventory''), TYPE + )), N''''); + + SET @payload = @payload + N''|ACTIVE_JOBS|'' + ISNULL(CONVERT(nvarchar(max), ( + SELECT job.job_id AS [@job_id], job.task_no AS [@task_no], job.tray_code AS [@tray_code], + job.source_space_id AS [@source_space_id], job.target_cargo_space_id AS [@target_space_id], + job.status AS [@status], job.in_or_out AS [@in_or_out], + job.create_time_raw AS [@create_time] + FROM alg.v_active_job job + WHERE job.warehouse_id = @warehouse_id AND job.source_lane_code = @lane_code + ORDER BY job.job_id + FOR XML PATH(''job''), ROOT(''jobs''), TYPE + )), N''''); + + SET @payload = @payload + N''|PROJECT_POLICY|'' + ISNULL(CONVERT(nvarchar(max), ( + SELECT policy.project_no AS [@project_no], policy.is_isolated AS [@is_isolated], + policy.is_common AS [@is_common], policy.allow_mixed AS [@allow_mixed] + FROM alg.project_policy policy + ORDER BY policy.project_no + FOR XML PATH(''project''), ROOT(''project_policy''), TYPE + )), N''''); + + SET @payload = @payload + N''|WAREHOUSE_POLICY|'' + ISNULL(CONVERT(nvarchar(max), ( + SELECT policy.warehouse_id AS [@warehouse_id], policy.target_fill_rate AS [@target_fill_rate], + policy.fifo_tolerance_hours AS [@fifo_tolerance_hours] + FROM alg.warehouse_policy policy + WHERE policy.warehouse_id = @warehouse_id + FOR XML PATH(''warehouse''), ROOT(''warehouse_policy''), TYPE + )), N''''); + + SET @payload = @payload + N''|RESERVATIONS|'' + ISNULL(CONVERT(nvarchar(max), ( + SELECT reservation.reservation_id AS [@reservation_id], reservation.space_id AS [@space_id], + reservation.project_no AS [@project_no], reservation.status AS [@status] + FROM alg.reservation reservation + WHERE reservation.warehouse_id = @warehouse_id AND reservation.lane_code = @lane_code + AND reservation.status = ''ACTIVE'' + ORDER BY reservation.space_id, reservation.reservation_id + FOR XML PATH(''reservation''), ROOT(''reservations''), TYPE + )), N''''); + + SET @semantic_fingerprint = HASHBYTES(''SHA2_256'', CONVERT(varbinary(max), @payload)); +END;'); +GO + +IF OBJECT_ID(N'alg.usp_rebuild_lane_state', N'P') IS NOT NULL DROP PROCEDURE alg.usp_rebuild_lane_state; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_rebuild_lane_state + @warehouse_id varchar(80) = NULL, + @lane_code varchar(80) = NULL +AS +BEGIN + SET NOCOUNT ON; + SELECT warehouse_id, lane_code, + COUNT(*) AS space_count, + SUM(CASE WHEN space_status = ''2'' OR stock_detail_count > 0 THEN 1 ELSE 0 END) AS occupied_count, + SUM(CASE WHEN inbound_available = 1 THEN 1 ELSE 0 END) AS available_count, + MAX(CASE WHEN pending_outbound = 1 THEN 1 ELSE 0 END) AS pending_outbound, + MAX(CASE WHEN has_gap = 1 THEN 1 ELSE 0 END) AS has_gap, + CAST(NULL AS varbinary(32)) AS semantic_fingerprint + INTO #source_state + FROM alg.v_space_state + WHERE (@warehouse_id IS NULL OR warehouse_id = @warehouse_id) + AND (@lane_code IS NULL OR lane_code = @lane_code) + GROUP BY warehouse_id, lane_code; + + DECLARE @fingerprint_warehouse varchar(80), @fingerprint_lane varchar(80), + @fingerprint varbinary(32); + DECLARE fingerprint_cursor CURSOR LOCAL FAST_FORWARD FOR + SELECT warehouse_id, lane_code FROM #source_state ORDER BY warehouse_id, lane_code; + OPEN fingerprint_cursor; + FETCH NEXT FROM fingerprint_cursor INTO @fingerprint_warehouse, @fingerprint_lane; + WHILE @@FETCH_STATUS = 0 + BEGIN + EXEC alg.usp_compute_lane_semantic_fingerprint + @warehouse_id = @fingerprint_warehouse, + @lane_code = @fingerprint_lane, + @semantic_fingerprint = @fingerprint OUTPUT, + @inventory_source = ''SNAPSHOT''; + UPDATE #source_state SET semantic_fingerprint = @fingerprint + WHERE warehouse_id = @fingerprint_warehouse AND lane_code = @fingerprint_lane; + FETCH NEXT FROM fingerprint_cursor INTO @fingerprint_warehouse, @fingerprint_lane; + END; + CLOSE fingerprint_cursor; + DEALLOCATE fingerprint_cursor; + + MERGE alg.lane_state WITH (HOLDLOCK) AS target + USING #source_state AS source + ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code + WHEN MATCHED AND (target.space_count <> source.space_count OR + target.occupied_count <> source.occupied_count OR + target.available_count <> source.available_count OR + target.pending_outbound <> source.pending_outbound OR + target.has_gap <> source.has_gap OR + target.semantic_fingerprint IS NULL OR + target.semantic_fingerprint <> source.semantic_fingerprint) + THEN UPDATE SET space_count = source.space_count, + occupied_count = source.occupied_count, + available_count = source.available_count, + pending_outbound = source.pending_outbound, + has_gap = source.has_gap, + semantic_fingerprint = source.semantic_fingerprint, + rebuilt_at = SYSUTCDATETIME() + WHEN NOT MATCHED BY TARGET THEN + INSERT (warehouse_id, lane_code, space_count, occupied_count, available_count, + pending_outbound, has_gap, semantic_fingerprint) + VALUES (source.warehouse_id, source.lane_code, source.space_count, source.occupied_count, + source.available_count, source.pending_outbound, source.has_gap, source.semantic_fingerprint) + WHEN NOT MATCHED BY SOURCE + AND (@warehouse_id IS NULL OR target.warehouse_id = @warehouse_id) + AND (@lane_code IS NULL OR target.lane_code = @lane_code) + THEN DELETE; +END;'); +GO + +IF OBJECT_ID(N'alg.usp_mark_dirty_lane', N'P') IS NOT NULL DROP PROCEDURE alg.usp_mark_dirty_lane; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_mark_dirty_lane + @warehouse_id varchar(80), + @lane_code varchar(80), + @topology_dirty bit = 0, + @reason_mask int = 0 +AS +BEGIN + SET NOCOUNT ON; + IF NULLIF(LTRIM(RTRIM(@warehouse_id)), '''') IS NULL + OR NULLIF(LTRIM(RTRIM(@lane_code)), '''') IS NULL + RETURN; + MERGE alg.dirty_lane_queue WITH (HOLDLOCK) AS target + USING (SELECT @warehouse_id AS warehouse_id, @lane_code AS lane_code) AS source + ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code + WHEN MATCHED THEN UPDATE SET + topology_dirty = CASE WHEN target.topology_dirty = 1 OR @topology_dirty = 1 THEN 1 ELSE 0 END, + reason_mask = target.reason_mask | @reason_mask, + change_count = target.change_count + 1, + last_changed_at = SYSUTCDATETIME() + WHEN NOT MATCHED THEN INSERT ( + warehouse_id, lane_code, topology_dirty, reason_mask, change_count, enqueued_at, last_changed_at) + VALUES (@warehouse_id, @lane_code, @topology_dirty, @reason_mask, 1, + SYSUTCDATETIME(), SYSUTCDATETIME()); +END;'); +GO + +IF OBJECT_ID(N'alg.usp_refresh_dirty_lanes', N'P') IS NOT NULL DROP PROCEDURE alg.usp_refresh_dirty_lanes; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_refresh_dirty_lanes + @warehouse_id varchar(80) +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT ON; + IF NULLIF(LTRIM(RTRIM(@warehouse_id)), '''') IS NULL + THROW 50002, ''warehouse_id is required'', 1; + + CREATE TABLE #dirty ( + warehouse_id varchar(80) NOT NULL, + lane_code varchar(80) NOT NULL, + topology_dirty bit NOT NULL, + reason_mask int NOT NULL, + change_count bigint NOT NULL, + enqueued_at datetime2 NOT NULL, + last_changed_at datetime2 NOT NULL, + PRIMARY KEY (warehouse_id, lane_code) + ); + + BEGIN TRANSACTION; + DELETE queue + OUTPUT deleted.warehouse_id, deleted.lane_code, deleted.topology_dirty, + deleted.reason_mask, deleted.change_count, deleted.enqueued_at, deleted.last_changed_at + INTO #dirty (warehouse_id, lane_code, topology_dirty, reason_mask, + change_count, enqueued_at, last_changed_at) + FROM alg.dirty_lane_queue queue WITH (UPDLOCK, READPAST, ROWLOCK) + WHERE queue.warehouse_id = @warehouse_id; + COMMIT TRANSACTION; + + IF NOT EXISTS (SELECT 1 FROM #dirty) + RETURN; + + BEGIN TRY + BEGIN TRANSACTION; + IF EXISTS (SELECT 1 FROM #dirty WHERE topology_dirty = 1) + BEGIN + EXEC alg.usp_rebuild_space_topology @warehouse_id = @warehouse_id; + + MERGE #dirty AS target + USING ( + SELECT DISTINCT warehouse_id, group_coding_no AS lane_code + FROM dbo.bas_cargo_space + WHERE warehouse_id = @warehouse_id + AND NULLIF(LTRIM(RTRIM(group_coding_no)), '''') IS NOT NULL + ) AS source + ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code + WHEN NOT MATCHED THEN INSERT ( + warehouse_id, lane_code, topology_dirty, reason_mask, + change_count, enqueued_at, last_changed_at) + VALUES (source.warehouse_id, source.lane_code, 1, 2, 1, + SYSUTCDATETIME(), SYSUTCDATETIME()); + + DELETE snapshot + FROM alg.inventory_item_snapshot snapshot + WHERE snapshot.warehouse_id = @warehouse_id + AND NOT EXISTS ( + SELECT 1 FROM dbo.bas_cargo_space cargo + WHERE cargo.cargo_space_id = snapshot.space_id + AND cargo.warehouse_id = snapshot.warehouse_id + ); + DELETE summary + FROM alg.space_inventory_summary summary + WHERE summary.warehouse_id = @warehouse_id + AND NOT EXISTS ( + SELECT 1 FROM dbo.bas_cargo_space cargo + WHERE cargo.cargo_space_id = summary.space_id + AND cargo.warehouse_id = summary.warehouse_id + ); + END; + + DELETE summary + FROM alg.space_inventory_summary summary + JOIN dbo.bas_cargo_space cargo ON cargo.cargo_space_id = summary.space_id + AND cargo.warehouse_id = summary.warehouse_id + JOIN #dirty dirty ON dirty.warehouse_id = cargo.warehouse_id + AND dirty.lane_code = cargo.group_coding_no; + + DELETE snapshot + FROM alg.inventory_item_snapshot snapshot + JOIN dbo.bas_cargo_space cargo ON cargo.cargo_space_id = snapshot.space_id + AND cargo.warehouse_id = snapshot.warehouse_id + JOIN #dirty dirty ON dirty.warehouse_id = cargo.warehouse_id + AND dirty.lane_code = cargo.group_coding_no; + + INSERT INTO alg.inventory_item_snapshot ( + warehouse_id, stock_id, space_id, tray_code, project_no, product_no, lot_no, + inbound_time_raw, inbound_at, quantity, out_quantity, synchronized_at) + SELECT cargo.warehouse_id, stock.stock_id, stock.cargo_space_id, stock.tray_code, + stock.spare4, stock.product_id, stock.lot_no, CONVERT(varchar(80), stock.in_date), + TRY_CONVERT(datetime2, stock.in_date), stock.quantity, stock.out_quantity, SYSUTCDATETIME() + FROM dbo.bas_stock stock + JOIN dbo.bas_cargo_space cargo ON cargo.cargo_space_id = stock.cargo_space_id + JOIN #dirty dirty ON dirty.warehouse_id = cargo.warehouse_id + AND dirty.lane_code = cargo.group_coding_no; + + INSERT INTO alg.space_inventory_summary ( + warehouse_id, space_id, stock_detail_count, stock_tray_count, + stock_project_count, stock_product_count, synchronized_at) + SELECT item.warehouse_id, item.space_id, COUNT(*), + COUNT(DISTINCT NULLIF(LTRIM(RTRIM(item.tray_code)), '''')), + COUNT(DISTINCT NULLIF(LTRIM(RTRIM(item.project_no)), '''')), + COUNT(DISTINCT NULLIF(LTRIM(RTRIM(item.product_no)), '''')), + SYSUTCDATETIME() + FROM alg.inventory_item_snapshot item + JOIN dbo.bas_cargo_space cargo ON cargo.cargo_space_id = item.space_id + AND cargo.warehouse_id = item.warehouse_id + JOIN #dirty dirty ON dirty.warehouse_id = cargo.warehouse_id + AND dirty.lane_code = cargo.group_coding_no + GROUP BY item.warehouse_id, item.space_id; + + DECLARE @lane_code varchar(80); + DECLARE dirty_cursor CURSOR LOCAL FAST_FORWARD FOR + SELECT lane_code FROM #dirty ORDER BY lane_code; + OPEN dirty_cursor; + FETCH NEXT FROM dirty_cursor INTO @lane_code; + WHILE @@FETCH_STATUS = 0 + BEGIN + EXEC alg.usp_rebuild_lane_state @warehouse_id = @warehouse_id, @lane_code = @lane_code; + FETCH NEXT FROM dirty_cursor INTO @lane_code; + END; + CLOSE dirty_cursor; + DEALLOCATE dirty_cursor; + + /* A claimed row retains its lease until release; otherwise queue_status = ''PENDING''. */ + MERGE alg.tidy_lane_queue WITH (HOLDLOCK) AS target + USING #dirty AS source + ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code + WHEN MATCHED THEN UPDATE SET + dirty_version = target.dirty_version + 1, + queue_status = CASE WHEN target.queue_status = ''CLAIMED'' THEN ''CLAIMED'' ELSE ''PENDING'' END, + reason_mask = target.reason_mask | source.reason_mask, + change_count = target.change_count + source.change_count, + last_dirty_at = CASE WHEN target.last_dirty_at >= source.last_changed_at + THEN target.last_dirty_at ELSE source.last_changed_at END, + last_error = NULL + WHEN NOT MATCHED THEN INSERT ( + warehouse_id, lane_code, dirty_version, queue_status, reason_mask, + change_count, last_dirty_at) + VALUES (source.warehouse_id, source.lane_code, 1, ''PENDING'', source.reason_mask, + source.change_count, source.last_changed_at); + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + IF XACT_STATE() <> 0 ROLLBACK TRANSACTION; + BEGIN TRY + BEGIN TRANSACTION; + MERGE alg.dirty_lane_queue WITH (HOLDLOCK) AS target + USING #dirty AS source + ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code + WHEN MATCHED THEN UPDATE SET + topology_dirty = CASE WHEN target.topology_dirty = 1 OR source.topology_dirty = 1 THEN 1 ELSE 0 END, + reason_mask = target.reason_mask | source.reason_mask, + change_count = target.change_count + source.change_count, + enqueued_at = CASE WHEN target.enqueued_at <= source.enqueued_at + THEN target.enqueued_at ELSE source.enqueued_at END, + last_changed_at = CASE WHEN target.last_changed_at >= source.last_changed_at + THEN target.last_changed_at ELSE source.last_changed_at END + WHEN NOT MATCHED THEN INSERT ( + warehouse_id, lane_code, topology_dirty, reason_mask, + change_count, enqueued_at, last_changed_at) + VALUES (source.warehouse_id, source.lane_code, source.topology_dirty, source.reason_mask, + source.change_count, source.enqueued_at, source.last_changed_at); + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + IF XACT_STATE() <> 0 ROLLBACK TRANSACTION; + THROW; + END CATCH; + THROW; + END CATCH; +END;'); +GO + +IF OBJECT_ID(N'alg.usp_claim_tidy_lane', N'P') IS NOT NULL DROP PROCEDURE alg.usp_claim_tidy_lane; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_claim_tidy_lane + @warehouse_id varchar(80) = NULL, + @eligible_lane_codes varchar(max) = NULL, + @claimed_by varchar(120), + @lease_seconds int = 120 +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT ON; + IF NULLIF(LTRIM(RTRIM(@claimed_by)), '''') IS NULL + THROW 50010, ''claimed_by is required'', 1; + IF @lease_seconds < 1 OR @lease_seconds > 3600 + THROW 50011, ''lease_seconds must be between 1 and 3600'', 1; + + DECLARE @claim_token uniqueidentifier = NEWID(), + @claimed_warehouse_id varchar(80), @claimed_lane_code varchar(80), + @claimed_dirty_version bigint, @now datetime2 = SYSUTCDATETIME(); + + BEGIN TRANSACTION; + ;WITH candidate AS ( + SELECT TOP (1) queue.* + FROM alg.tidy_lane_queue queue WITH (UPDLOCK, READPAST, ROWLOCK) + WHERE (@warehouse_id IS NULL OR queue.warehouse_id = @warehouse_id) + AND (NULLIF(LTRIM(RTRIM(@eligible_lane_codes)), '''') IS NULL + OR EXISTS ( + SELECT 1 + FROM STRING_SPLIT(@eligible_lane_codes, '','') eligible + WHERE LTRIM(RTRIM(eligible.value)) = queue.lane_code + )) + AND (queue.queue_status = ''PENDING'' + OR (queue.queue_status = ''CLAIMED'' AND queue.lease_expires_at <= @now)) + ORDER BY queue.last_dirty_at, queue.warehouse_id, queue.lane_code + ) + UPDATE candidate + SET queue_status = ''CLAIMED'', + claim_token = @claim_token, + claimed_version = dirty_version, + claimed_by = @claimed_by, + claimed_at = @now, + lease_expires_at = DATEADD(second, @lease_seconds, @now), + last_error = NULL; + + SELECT TOP (1) + @claimed_warehouse_id = warehouse_id, + @claimed_lane_code = lane_code, + @claimed_dirty_version = claimed_version + FROM alg.tidy_lane_queue + WHERE claim_token = @claim_token; + COMMIT TRANSACTION; + + SELECT @claimed_warehouse_id AS warehouse_id, + @claimed_lane_code AS lane_code, + @claimed_dirty_version AS dirty_version, + CASE WHEN @claimed_warehouse_id IS NULL THEN NULL ELSE @claim_token END AS claim_token, + CASE WHEN @claimed_warehouse_id IS NULL THEN NULL + ELSE DATEADD(second, @lease_seconds, @now) END AS lease_expires_at; +END;'); +GO + +IF OBJECT_ID(N'alg.usp_release_tidy_lane', N'P') IS NOT NULL DROP PROCEDURE alg.usp_release_tidy_lane; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_release_tidy_lane + @warehouse_id varchar(80), + @lane_code varchar(80), + @claim_token uniqueidentifier, + @claimed_version bigint, + @completed bit, + @last_error varchar(2000) = NULL +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT ON; + + DECLARE @released TABLE (queue_status varchar(20), dirty_version bigint); + BEGIN TRANSACTION; + UPDATE alg.tidy_lane_queue WITH (UPDLOCK, ROWLOCK) + SET queue_status = CASE WHEN dirty_version > @claimed_version OR @completed = 0 + THEN ''PENDING'' ELSE ''COMPLETED'' END, + claim_token = NULL, + claimed_version = NULL, + claimed_by = NULL, + claimed_at = NULL, + lease_expires_at = NULL, + last_error = @last_error + OUTPUT inserted.queue_status, inserted.dirty_version + INTO @released (queue_status, dirty_version) + WHERE warehouse_id = @warehouse_id + AND lane_code = @lane_code + AND queue_status = ''CLAIMED'' + AND claim_token = @claim_token + AND claimed_version = @claimed_version; + COMMIT TRANSACTION; + + SELECT CASE WHEN EXISTS (SELECT 1 FROM @released) THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS released, + queue_status, dirty_version + FROM @released + UNION ALL + SELECT CAST(0 AS bit), NULL, NULL + WHERE NOT EXISTS (SELECT 1 FROM @released); +END;'); +GO + +IF OBJECT_ID(N'alg.usp_complete_move_job', N'P') IS NOT NULL DROP PROCEDURE alg.usp_complete_move_job; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_complete_move_job + @v_job_id varchar(255), + @v_result int OUTPUT +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT ON; + SET @v_result = 0; + + DECLARE @source_space_id varchar(255); + DECLARE @target_space_id varchar(255); + DECLARE @tray_code varchar(255); + DECLARE @finished_at varchar(19) = CONVERT(varchar(19), GETDATE(), 120); + + BEGIN TRANSACTION; + SELECT @source_space_id = cargo_space_id, + @target_space_id = target_cargo_space_id, + @tray_code = tray_code + FROM dbo.mydo_job WITH (UPDLOCK, HOLDLOCK) + WHERE job_id = @v_job_id + AND in_or_out = ''28''; + + IF @source_space_id IS NULL OR @target_space_id IS NULL OR @tray_code IS NULL + THROW 51400, ''Algorithm move job is missing or invalid'', 1; + + UPDATE dbo.bas_stock + SET cargo_space_id = @target_space_id, + out_quantity = 0 + WHERE cargo_space_id = @source_space_id + AND tray_code = @tray_code; + IF @@ROWCOUNT = 0 + THROW 51401, ''Algorithm move stock is not at its source space'', 1; + + UPDATE dbo.bas_cargo_space + SET status = ''1'', tray_code = '''' + WHERE cargo_space_id = @source_space_id; + UPDATE dbo.bas_cargo_space + SET status = ''2'', tray_code = @tray_code + WHERE cargo_space_id = @target_space_id; + + UPDATE dbo.mydo_job + SET status = ''4'', finish_time = @finished_at + WHERE job_id = @v_job_id + AND in_or_out = ''28''; + INSERT INTO dbo.mydo_job_finish + SELECT job.* FROM dbo.mydo_job job + WHERE job.job_id = @v_job_id + AND job.in_or_out = ''28''; + DELETE FROM dbo.mydo_job + WHERE job_id = @v_job_id + AND in_or_out = ''28''; + + INSERT INTO dbo.move_msg (id, tray_code, old_space, new_space, status) + VALUES (NEWID(), @tray_code, @source_space_id, @target_space_id, ''0''); + + COMMIT TRANSACTION; + SET @v_result = 10; +END;'); +GO + +IF OBJECT_ID(N'alg.usp_sync_replay_sequences', N'P') IS NOT NULL DROP PROCEDURE alg.usp_sync_replay_sequences; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_sync_replay_sequences +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT ON; + + DECLARE @lock_result int; + BEGIN TRANSACTION; + EXEC @lock_result = sys.sp_getapplock + @Resource = ''alg.usp_sync_replay_sequences'', + @LockMode = ''Exclusive'', + @LockOwner = ''Transaction'', + @LockTimeout = 10000; + IF @lock_result < 0 + THROW 50012, ''Unable to acquire replay sequence lock'', 1; + + /* Regression fixture: imported history already contains CK202607210002. */ + ;WITH all_job_ids AS ( + SELECT job_id FROM dbo.mydo_job + UNION ALL + SELECT job_id FROM dbo.mydo_job_finish + ), parsed AS ( + SELECT LEFT(job_id, 2) AS job_type, + SUBSTRING(job_id, 3, 8) AS job_date, + TRY_CONVERT(int, RIGHT(job_id, 4)) AS job_sequence + FROM all_job_ids + WHERE LEN(job_id) = 14 + AND TRY_CONVERT(date, SUBSTRING(job_id, 3, 8), 112) IS NOT NULL + AND TRY_CONVERT(int, RIGHT(job_id, 4)) IS NOT NULL + ), ranked AS ( + SELECT job_type, job_date, job_sequence, + ROW_NUMBER() OVER (PARTITION BY job_type ORDER BY job_date DESC, job_sequence DESC) AS row_no + FROM parsed + ) + UPDATE generator WITH (UPDLOCK, HOLDLOCK) + SET stock_id = ranked.job_date, + job_id = RIGHT(''0000'' + CONVERT(varchar(20), ranked.job_sequence), 4) + FROM dbo.bas_job_id generator + JOIN ranked ON ranked.job_type = generator.type AND ranked.row_no = 1 + WHERE TRY_CONVERT(bigint, ranked.job_date + RIGHT(''0000'' + CONVERT(varchar(20), ranked.job_sequence), 4)) + > TRY_CONVERT(bigint, ISNULL(generator.stock_id, ''00000000'') + + RIGHT(''0000'' + ISNULL(generator.job_id, ''0''), 4)); + + ;WITH all_task_numbers AS ( + SELECT TRY_CONVERT(int, task_no) AS task_no FROM dbo.mydo_job + UNION ALL + SELECT TRY_CONVERT(int, task_no) AS task_no FROM dbo.mydo_job_finish + ), observed AS ( + SELECT generator.id, MAX(numbers.task_no) AS max_task_no + FROM dbo.bas_task_no generator + JOIN all_task_numbers numbers + ON numbers.task_no BETWEEN generator.min_no AND generator.max_no + GROUP BY generator.id + ) + UPDATE generator WITH (UPDLOCK, HOLDLOCK) + SET task_no = observed.max_task_no + FROM dbo.bas_task_no generator + JOIN observed ON observed.id = generator.id + WHERE observed.max_task_no > ISNULL(generator.task_no, generator.min_no - 1); + + COMMIT TRANSACTION; + + SELECT type, stock_id, job_id FROM dbo.bas_job_id WHERE type IN (''RK'', ''CK'', ''ZC'') ORDER BY type; + SELECT id, task_type, task_no, min_no, max_no FROM dbo.bas_task_no WHERE id IN (1, 21) ORDER BY id; +END;'); +GO + +IF OBJECT_ID(N'alg.usp_try_reserve_inbound', N'P') IS NOT NULL DROP PROCEDURE alg.usp_try_reserve_inbound; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_try_reserve_inbound + @warehouse_id varchar(80), + @lane_code varchar(80), + @space_id varchar(80), + @project_no varchar(255), + @expected_state_version binary(8), + @reservation_id uniqueidentifier = NULL +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT ON; + IF @reservation_id IS NULL SET @reservation_id = NEWID(); + IF @expected_state_version IS NULL + BEGIN + SELECT CAST(''CONFLICT'' AS varchar(20)) AS result, CAST(''LANE_VERSION_MISMATCH'' AS varchar(80)) AS reason, @reservation_id AS reservation_id; + RETURN; + END; + BEGIN TRANSACTION; + + DECLARE @current_version binary(8), @stored_semantic_fingerprint varbinary(32), + @live_semantic_fingerprint varbinary(32), @target_status varchar(5), @target_locked varchar(5), + @target_tray varchar(255), @target_depth int, @role varchar(40), @target_stock_count int, + @has_inner_candidate bit, @has_gap bit, @has_active_reservation bit, @pending_outbound bit, + @lane_lock_count int, @stock_lock_count int, @job_lock_count int, + @role_lock_count int, @topology_lock_count int, @project_policy_lock_count int, + @warehouse_policy_lock_count int, @reservation_lock_count int; + + /* Hold source-row and key-range locks through eligibility recomputation. */ + SELECT @current_version = state_version, @stored_semantic_fingerprint = semantic_fingerprint + FROM alg.lane_state WITH (UPDLOCK, HOLDLOCK) + WHERE warehouse_id = @warehouse_id AND lane_code = @lane_code; + + IF @current_version IS NULL OR @current_version <> @expected_state_version + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(''CONFLICT'' AS varchar(20)) AS result, CAST(''LANE_VERSION_MISMATCH'' AS varchar(80)) AS reason, @reservation_id AS reservation_id; + RETURN; + END; + + SELECT @target_status = status, @target_locked = locked, @target_tray = tray_code, + @target_depth = TRY_CONVERT(int, group_coding) + FROM dbo.bas_cargo_space WITH (UPDLOCK, HOLDLOCK) + WHERE cargo_space_id = @space_id AND warehouse_id = @warehouse_id AND group_coding_no = @lane_code; + + SELECT @lane_lock_count = COUNT(*) + FROM dbo.bas_cargo_space WITH (UPDLOCK, HOLDLOCK) + WHERE warehouse_id = @warehouse_id AND group_coding_no = @lane_code; + + SELECT @stock_lock_count = COUNT(*) + FROM dbo.bas_stock stock WITH (UPDLOCK, HOLDLOCK) + JOIN dbo.bas_cargo_space lane_space WITH (UPDLOCK, HOLDLOCK) ON lane_space.cargo_space_id = stock.cargo_space_id + WHERE lane_space.warehouse_id = @warehouse_id AND lane_space.group_coding_no = @lane_code; + + SELECT @job_lock_count = COUNT(*) + FROM dbo.mydo_job WITH (UPDLOCK, HOLDLOCK) + WHERE warehouse_id = @warehouse_id + AND (finish_time IS NULL OR LTRIM(RTRIM(finish_time)) = ''''); + + SELECT @role_lock_count = COUNT(*) + FROM alg.space_role WITH (UPDLOCK, HOLDLOCK) + WHERE space_id IN (SELECT cargo_space_id FROM dbo.bas_cargo_space + WHERE warehouse_id = @warehouse_id AND group_coding_no = @lane_code); + + SELECT @topology_lock_count = COUNT(*) + FROM alg.space_topology WITH (UPDLOCK, HOLDLOCK) + WHERE warehouse_id = @warehouse_id AND lane_code = @lane_code; + + SELECT @project_policy_lock_count = COUNT(*) + FROM alg.project_policy WITH (UPDLOCK, HOLDLOCK); + + SELECT @warehouse_policy_lock_count = COUNT(*) + FROM alg.warehouse_policy WITH (UPDLOCK, HOLDLOCK) + WHERE warehouse_id = @warehouse_id; + + SELECT @reservation_lock_count = COUNT(*) + FROM alg.reservation WITH (UPDLOCK, HOLDLOCK) + WHERE warehouse_id = @warehouse_id AND lane_code = @lane_code AND status = ''ACTIVE''; + + EXEC alg.usp_compute_lane_semantic_fingerprint + @warehouse_id = @warehouse_id, + @lane_code = @lane_code, + @semantic_fingerprint = @live_semantic_fingerprint OUTPUT, + @inventory_source = ''LIVE''; + + IF @stored_semantic_fingerprint IS NULL OR @live_semantic_fingerprint IS NULL + OR @stored_semantic_fingerprint <> @live_semantic_fingerprint + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(''CONFLICT'' AS varchar(20)) AS result, CAST(''LANE_VERSION_MISMATCH'' AS varchar(80)) AS reason, @reservation_id AS reservation_id; + RETURN; + END; + + SELECT @target_stock_count = COUNT(*) + FROM dbo.bas_stock WITH (UPDLOCK, HOLDLOCK) + WHERE cargo_space_id = @space_id; + + SELECT @role = role + FROM alg.space_role WITH (UPDLOCK, HOLDLOCK) + WHERE space_id = @space_id; + + SELECT @has_active_reservation = CASE WHEN EXISTS ( + SELECT 1 FROM alg.reservation WITH (UPDLOCK, HOLDLOCK) WHERE space_id = @space_id AND status = ''ACTIVE'' + ) THEN 1 ELSE 0 END; + + SELECT @has_inner_candidate = CASE WHEN EXISTS ( + SELECT 1 + FROM dbo.bas_cargo_space inner_candidate WITH (UPDLOCK, HOLDLOCK) + LEFT JOIN dbo.bas_stock inner_stock WITH (UPDLOCK, HOLDLOCK) ON inner_stock.cargo_space_id = inner_candidate.cargo_space_id + WHERE inner_candidate.warehouse_id = @warehouse_id + AND inner_candidate.group_coding_no = @lane_code + AND TRY_CONVERT(int, inner_candidate.group_coding) < @target_depth + AND inner_candidate.status = ''1'' + AND NULLIF(LTRIM(RTRIM(inner_candidate.tray_code)), '''') IS NULL + AND inner_stock.cargo_space_id IS NULL + ) THEN 1 ELSE 0 END; + + SELECT @has_gap = CASE WHEN EXISTS ( + SELECT 1 + FROM dbo.bas_cargo_space inner_space WITH (UPDLOCK, HOLDLOCK) + JOIN dbo.bas_cargo_space outer_space WITH (UPDLOCK, HOLDLOCK) + ON outer_space.warehouse_id = inner_space.warehouse_id + AND outer_space.group_coding_no = inner_space.group_coding_no + AND TRY_CONVERT(int, outer_space.group_coding) > TRY_CONVERT(int, inner_space.group_coding) + WHERE inner_space.warehouse_id = @warehouse_id + AND inner_space.group_coding_no = @lane_code + AND NULLIF(LTRIM(RTRIM(inner_space.tray_code)), '''') IS NULL + AND NOT EXISTS ( + SELECT 1 FROM dbo.bas_stock inner_stock WITH (UPDLOCK, HOLDLOCK) + WHERE inner_stock.cargo_space_id = inner_space.cargo_space_id + ) + AND ( + NULLIF(LTRIM(RTRIM(outer_space.tray_code)), '''') IS NOT NULL + OR EXISTS ( + SELECT 1 FROM dbo.bas_stock outer_stock WITH (UPDLOCK, HOLDLOCK) + WHERE outer_stock.cargo_space_id = outer_space.cargo_space_id + ) + ) + ) THEN 1 ELSE 0 END; + + ;WITH tray_candidates AS ( + SELECT j.job_id, COUNT(DISTINCT s.cargo_space_id) AS space_count, MIN(s.cargo_space_id) AS cargo_space_id + FROM dbo.mydo_job j WITH (UPDLOCK, HOLDLOCK) + JOIN dbo.bas_stock s WITH (UPDLOCK, HOLDLOCK) ON s.tray_code = NULLIF(LTRIM(RTRIM(j.tray_code)), '''') + JOIN dbo.bas_cargo_space c WITH (UPDLOCK, HOLDLOCK) ON c.cargo_space_id = s.cargo_space_id AND c.warehouse_id = j.warehouse_id + WHERE j.warehouse_id = @warehouse_id + GROUP BY j.job_id + ) + SELECT @pending_outbound = CASE WHEN EXISTS ( + SELECT 1 + FROM dbo.mydo_job j WITH (UPDLOCK, HOLDLOCK) + LEFT JOIN dbo.bas_cargo_space source_space WITH (UPDLOCK, HOLDLOCK) + ON source_space.cargo_space_id = NULLIF(LTRIM(RTRIM(j.cargo_space_id)), '''') + AND source_space.warehouse_id = j.warehouse_id + LEFT JOIN tray_candidates ON tray_candidates.job_id = j.job_id + LEFT JOIN dbo.bas_cargo_space resolved_space WITH (UPDLOCK, HOLDLOCK) + ON resolved_space.cargo_space_id = COALESCE(source_space.cargo_space_id, + CASE WHEN tray_candidates.space_count = 1 THEN tray_candidates.cargo_space_id END) + WHERE (j.finish_time IS NULL OR LTRIM(RTRIM(j.finish_time)) = '''') + AND j.in_or_out >= 20 + AND j.warehouse_id = @warehouse_id + AND resolved_space.group_coding_no = @lane_code + ) THEN 1 ELSE 0 END; + + IF ISNULL(@pending_outbound, 0) = 1 + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(''CONFLICT'' AS varchar(20)) AS result, CAST(''PENDING_OUTBOUND'' AS varchar(80)) AS reason, @reservation_id AS reservation_id; + RETURN; + END; + + IF @target_status IS NULL OR @target_status <> ''1'' OR + (NULLIF(LTRIM(RTRIM(@target_locked)), '''') IS NOT NULL AND LTRIM(RTRIM(@target_locked)) NOT IN (''0'', ''N'')) OR + NULLIF(LTRIM(RTRIM(@target_tray)), '''') IS NOT NULL OR + ISNULL(@target_stock_count, 0) <> 0 OR @target_depth IS NULL OR + ISNULL(@role, ''STORAGE'') <> ''STORAGE'' OR ISNULL(@has_active_reservation, 0) = 1 OR + ISNULL(@has_inner_candidate, 0) = 1 OR ISNULL(@has_gap, 0) = 1 + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(''CONFLICT'' AS varchar(20)) AS result, CAST(''SPACE_NOT_ELIGIBLE'' AS varchar(80)) AS reason, @reservation_id AS reservation_id; + RETURN; + END; + + BEGIN TRY + INSERT INTO alg.reservation (reservation_id, warehouse_id, lane_code, space_id, project_no, status) + VALUES (@reservation_id, @warehouse_id, @lane_code, @space_id, @project_no, ''ACTIVE''); + EXEC alg.usp_rebuild_lane_state @warehouse_id, @lane_code; + COMMIT TRANSACTION; + SELECT CAST(''RESERVED'' AS varchar(20)) AS result, CAST(NULL AS varchar(80)) AS reason, @reservation_id AS reservation_id; + END TRY + BEGIN CATCH + DECLARE @error_number int = ERROR_NUMBER(); + IF XACT_STATE() <> 0 ROLLBACK TRANSACTION; + IF @error_number IN (2601, 2627) + BEGIN + SELECT CAST(''CONFLICT'' AS varchar(20)) AS result, CAST(''ACTIVE_RESERVATION_EXISTS'' AS varchar(80)) AS reason, @reservation_id AS reservation_id; + RETURN; + END; + THROW; + END CATCH; +END;'); +GO + +IF OBJECT_ID(N'alg.usp_release_reservation', N'P') IS NOT NULL DROP PROCEDURE alg.usp_release_reservation; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_release_reservation + @warehouse_id varchar(80), + @reservation_id uniqueidentifier +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT ON; + DECLARE @lane_code varchar(80); + BEGIN TRANSACTION; + SELECT @lane_code = lane_code + FROM alg.reservation WITH (UPDLOCK, HOLDLOCK) + WHERE reservation_id = @reservation_id AND warehouse_id = @warehouse_id AND status = ''ACTIVE''; + + IF @lane_code IS NULL + BEGIN + ROLLBACK TRANSACTION; + SELECT CAST(''NOT_FOUND'' AS varchar(20)) AS result, @reservation_id AS reservation_id; + RETURN; + END; + + UPDATE alg.reservation + SET status = ''RELEASED'', released_at = SYSUTCDATETIME() + WHERE reservation_id = @reservation_id AND warehouse_id = @warehouse_id; + EXEC alg.usp_rebuild_lane_state @warehouse_id, @lane_code; + COMMIT TRANSACTION; + SELECT CAST(''RELEASED'' AS varchar(20)) AS result, @reservation_id AS reservation_id; +END;'); +GO + +IF OBJECT_ID(N'alg.usp_acquire_deep_workflow_lock', N'P') IS NOT NULL DROP PROCEDURE alg.usp_acquire_deep_workflow_lock; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_acquire_deep_workflow_lock + @request_id varchar(80), + @warehouse_id varchar(80), + @floor_no int +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT ON; + DECLARE @owner varchar(80); + BEGIN TRANSACTION; + SELECT @owner = request_id + FROM alg.deep_workflow_lock WITH (UPDLOCK, HOLDLOCK) + WHERE warehouse_id = @warehouse_id AND floor_no = @floor_no AND status = ''ACTIVE''; + + IF @owner IS NOT NULL + BEGIN + COMMIT TRANSACTION; + SELECT CONVERT(bit, CASE WHEN @owner = @request_id THEN 1 ELSE 0 END) AS acquired; + RETURN; + END; + + INSERT INTO alg.deep_workflow_lock (lock_id, request_id, warehouse_id, floor_no, status) + VALUES (NEWID(), @request_id, @warehouse_id, @floor_no, ''ACTIVE''); + COMMIT TRANSACTION; + SELECT CONVERT(bit, 1) AS acquired; +END;'); +GO + +IF OBJECT_ID(N'alg.usp_release_deep_workflow_lock', N'P') IS NOT NULL DROP PROCEDURE alg.usp_release_deep_workflow_lock; +GO +EXEC(N' +CREATE PROCEDURE alg.usp_release_deep_workflow_lock + @request_id varchar(80), + @warehouse_id varchar(80), + @floor_no int +AS +BEGIN + SET NOCOUNT ON; + SET XACT_ABORT ON; + BEGIN TRANSACTION; + UPDATE alg.deep_workflow_lock WITH (UPDLOCK, HOLDLOCK) + SET status = ''RELEASED'', released_at = SYSUTCDATETIME() + WHERE request_id = @request_id AND warehouse_id = @warehouse_id + AND floor_no = @floor_no AND status = ''ACTIVE''; + DECLARE @released bit = CASE WHEN @@ROWCOUNT = 1 THEN 1 ELSE 0 END; + COMMIT TRANSACTION; + SELECT @released AS released; +END;'); +GO + +IF OBJECT_ID(N'dbo.trg_alg_dirty_bas_stock', N'TR') IS NOT NULL DROP TRIGGER dbo.trg_alg_dirty_bas_stock; +GO +EXEC(N' +CREATE TRIGGER dbo.trg_alg_dirty_bas_stock +ON dbo.bas_stock +AFTER INSERT, UPDATE, DELETE +AS +BEGIN + SET NOCOUNT ON; + ;WITH changed AS ( + SELECT cargo.warehouse_id, cargo.group_coding_no AS lane_code + FROM inserted row_data + JOIN dbo.bas_cargo_space cargo ON cargo.cargo_space_id = row_data.cargo_space_id + UNION + SELECT cargo.warehouse_id, cargo.group_coding_no + FROM deleted row_data + JOIN dbo.bas_cargo_space cargo ON cargo.cargo_space_id = row_data.cargo_space_id + ), source AS ( + SELECT warehouse_id, lane_code + FROM changed + WHERE NULLIF(LTRIM(RTRIM(warehouse_id)), '''') IS NOT NULL + AND NULLIF(LTRIM(RTRIM(lane_code)), '''') IS NOT NULL + GROUP BY warehouse_id, lane_code + ) + MERGE alg.dirty_lane_queue WITH (HOLDLOCK) AS target + USING source ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code + WHEN MATCHED THEN UPDATE SET reason_mask = target.reason_mask | 1, + change_count = target.change_count + 1, last_changed_at = SYSUTCDATETIME() + WHEN NOT MATCHED THEN INSERT ( + warehouse_id, lane_code, topology_dirty, reason_mask, change_count, enqueued_at, last_changed_at) + VALUES (source.warehouse_id, source.lane_code, 0, 1, 1, SYSUTCDATETIME(), SYSUTCDATETIME()); +END;'); +GO + +IF OBJECT_ID(N'dbo.trg_alg_dirty_bas_cargo_space', N'TR') IS NOT NULL DROP TRIGGER dbo.trg_alg_dirty_bas_cargo_space; +GO +EXEC(N' +CREATE TRIGGER dbo.trg_alg_dirty_bas_cargo_space +ON dbo.bas_cargo_space +AFTER INSERT, UPDATE, DELETE +AS +BEGIN + SET NOCOUNT ON; + ;WITH paired AS ( + SELECT i.cargo_space_id AS inserted_id, d.cargo_space_id AS deleted_id, + i.warehouse_id AS inserted_warehouse, i.group_coding_no AS inserted_lane, + d.warehouse_id AS deleted_warehouse, d.group_coding_no AS deleted_lane, + CASE WHEN i.cargo_space_id IS NULL OR d.cargo_space_id IS NULL + OR ISNULL(i.warehouse_id, '''') <> ISNULL(d.warehouse_id, '''') + OR ISNULL(i.group_coding_no, '''') <> ISNULL(d.group_coding_no, '''') + OR ISNULL(i.group_coding, '''') <> ISNULL(d.group_coding, '''') + OR ISNULL(i.the_platoon, -2147483648) <> ISNULL(d.the_platoon, -2147483648) + OR ISNULL(i.the_column, -2147483648) <> ISNULL(d.the_column, -2147483648) + OR ISNULL(i.the_floor, -2147483648) <> ISNULL(d.the_floor, -2147483648) + THEN 1 ELSE 0 END AS topology_dirty + FROM inserted i + FULL OUTER JOIN deleted d ON d.cargo_space_id = i.cargo_space_id + ), changed AS ( + SELECT inserted_warehouse AS warehouse_id, inserted_lane AS lane_code, topology_dirty + FROM paired WHERE inserted_id IS NOT NULL + UNION ALL + SELECT deleted_warehouse, deleted_lane, topology_dirty + FROM paired WHERE deleted_id IS NOT NULL + ), source AS ( + SELECT warehouse_id, lane_code, CONVERT(bit, MAX(topology_dirty)) AS topology_dirty + FROM changed + WHERE NULLIF(LTRIM(RTRIM(warehouse_id)), '''') IS NOT NULL + AND NULLIF(LTRIM(RTRIM(lane_code)), '''') IS NOT NULL + GROUP BY warehouse_id, lane_code + ) + MERGE alg.dirty_lane_queue WITH (HOLDLOCK) AS target + USING source ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code + WHEN MATCHED THEN UPDATE SET + topology_dirty = CASE WHEN target.topology_dirty = 1 OR source.topology_dirty = 1 THEN 1 ELSE 0 END, + reason_mask = target.reason_mask | 2, change_count = target.change_count + 1, + last_changed_at = SYSUTCDATETIME() + WHEN NOT MATCHED THEN INSERT ( + warehouse_id, lane_code, topology_dirty, reason_mask, change_count, enqueued_at, last_changed_at) + VALUES (source.warehouse_id, source.lane_code, source.topology_dirty, 2, 1, + SYSUTCDATETIME(), SYSUTCDATETIME()); +END;'); +GO + +IF OBJECT_ID(N'dbo.trg_alg_dirty_mydo_job', N'TR') IS NOT NULL DROP TRIGGER dbo.trg_alg_dirty_mydo_job; +GO +EXEC(N' +CREATE TRIGGER dbo.trg_alg_dirty_mydo_job +ON dbo.mydo_job +AFTER INSERT, UPDATE, DELETE +AS +BEGIN + SET NOCOUNT ON; + ;WITH changed_jobs AS ( + SELECT warehouse_id, cargo_space_id, target_cargo_space_id, tray_code FROM inserted + UNION ALL + SELECT warehouse_id, cargo_space_id, target_cargo_space_id, tray_code FROM deleted + ), changed AS ( + SELECT job.warehouse_id, source_space.group_coding_no AS lane_code + FROM changed_jobs job + JOIN dbo.bas_cargo_space source_space + ON source_space.warehouse_id = job.warehouse_id + AND source_space.cargo_space_id = NULLIF(LTRIM(RTRIM(job.cargo_space_id)), '''') + UNION + SELECT job.warehouse_id, target_space.group_coding_no + FROM changed_jobs job + JOIN dbo.bas_cargo_space target_space + ON target_space.warehouse_id = job.warehouse_id + AND target_space.cargo_space_id = NULLIF(LTRIM(RTRIM(job.target_cargo_space_id)), '''') + UNION + SELECT job.warehouse_id, tray_space.group_coding_no + FROM changed_jobs job + JOIN dbo.bas_stock stock ON stock.tray_code = NULLIF(LTRIM(RTRIM(job.tray_code)), '''') + JOIN dbo.bas_cargo_space tray_space ON tray_space.cargo_space_id = stock.cargo_space_id + AND tray_space.warehouse_id = job.warehouse_id + ), source AS ( + SELECT warehouse_id, lane_code FROM changed + WHERE NULLIF(LTRIM(RTRIM(warehouse_id)), '''') IS NOT NULL + AND NULLIF(LTRIM(RTRIM(lane_code)), '''') IS NOT NULL + GROUP BY warehouse_id, lane_code + ) + MERGE alg.dirty_lane_queue WITH (HOLDLOCK) AS target + USING source ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code + WHEN MATCHED THEN UPDATE SET reason_mask = target.reason_mask | 4, + change_count = target.change_count + 1, last_changed_at = SYSUTCDATETIME() + WHEN NOT MATCHED THEN INSERT ( + warehouse_id, lane_code, topology_dirty, reason_mask, change_count, enqueued_at, last_changed_at) + VALUES (source.warehouse_id, source.lane_code, 0, 4, 1, SYSUTCDATETIME(), SYSUTCDATETIME()); +END;'); +GO + +IF OBJECT_ID(N'alg.trg_alg_dirty_space_role', N'TR') IS NOT NULL DROP TRIGGER alg.trg_alg_dirty_space_role; +GO +EXEC(N' +CREATE TRIGGER alg.trg_alg_dirty_space_role +ON alg.space_role +AFTER INSERT, UPDATE, DELETE +AS +BEGIN + SET NOCOUNT ON; + ;WITH changed_space AS ( + SELECT space_id FROM inserted UNION SELECT space_id FROM deleted + ), source AS ( + SELECT cargo.warehouse_id, cargo.group_coding_no AS lane_code + FROM changed_space changed + JOIN dbo.bas_cargo_space cargo ON cargo.cargo_space_id = changed.space_id + GROUP BY cargo.warehouse_id, cargo.group_coding_no + ) + MERGE alg.dirty_lane_queue WITH (HOLDLOCK) AS target + USING source ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code + WHEN MATCHED THEN UPDATE SET reason_mask = target.reason_mask | 8, + change_count = target.change_count + 1, last_changed_at = SYSUTCDATETIME() + WHEN NOT MATCHED THEN INSERT ( + warehouse_id, lane_code, topology_dirty, reason_mask, change_count, enqueued_at, last_changed_at) + VALUES (source.warehouse_id, source.lane_code, 0, 8, 1, SYSUTCDATETIME(), SYSUTCDATETIME()); +END;'); +GO + +IF OBJECT_ID(N'alg.trg_alg_dirty_project_policy', N'TR') IS NOT NULL DROP TRIGGER alg.trg_alg_dirty_project_policy; +GO +EXEC(N' +CREATE TRIGGER alg.trg_alg_dirty_project_policy +ON alg.project_policy +AFTER INSERT, UPDATE, DELETE +AS +BEGIN + SET NOCOUNT ON; + IF NOT EXISTS (SELECT 1 FROM inserted) AND NOT EXISTS (SELECT 1 FROM deleted) RETURN; + ;WITH source AS ( + SELECT warehouse_id, group_coding_no AS lane_code + FROM dbo.bas_cargo_space + GROUP BY warehouse_id, group_coding_no + ) + MERGE alg.dirty_lane_queue WITH (HOLDLOCK) AS target + USING source ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code + WHEN MATCHED THEN UPDATE SET reason_mask = target.reason_mask | 16, + change_count = target.change_count + 1, last_changed_at = SYSUTCDATETIME() + WHEN NOT MATCHED THEN INSERT ( + warehouse_id, lane_code, topology_dirty, reason_mask, change_count, enqueued_at, last_changed_at) + VALUES (source.warehouse_id, source.lane_code, 0, 16, 1, SYSUTCDATETIME(), SYSUTCDATETIME()); +END;'); +GO + +IF OBJECT_ID(N'alg.trg_alg_dirty_warehouse_policy', N'TR') IS NOT NULL DROP TRIGGER alg.trg_alg_dirty_warehouse_policy; +GO +EXEC(N' +CREATE TRIGGER alg.trg_alg_dirty_warehouse_policy +ON alg.warehouse_policy +AFTER INSERT, UPDATE, DELETE +AS +BEGIN + SET NOCOUNT ON; + ;WITH changed_warehouse AS ( + SELECT warehouse_id FROM inserted UNION SELECT warehouse_id FROM deleted + ), source AS ( + SELECT cargo.warehouse_id, cargo.group_coding_no AS lane_code + FROM changed_warehouse changed + JOIN dbo.bas_cargo_space cargo ON cargo.warehouse_id = changed.warehouse_id + GROUP BY cargo.warehouse_id, cargo.group_coding_no + ) + MERGE alg.dirty_lane_queue WITH (HOLDLOCK) AS target + USING source ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code + WHEN MATCHED THEN UPDATE SET reason_mask = target.reason_mask | 32, + change_count = target.change_count + 1, last_changed_at = SYSUTCDATETIME() + WHEN NOT MATCHED THEN INSERT ( + warehouse_id, lane_code, topology_dirty, reason_mask, change_count, enqueued_at, last_changed_at) + VALUES (source.warehouse_id, source.lane_code, 0, 32, 1, SYSUTCDATETIME(), SYSUTCDATETIME()); +END;'); +GO + +IF NOT EXISTS (SELECT 1 FROM alg.space_topology) + AND NOT EXISTS (SELECT 1 FROM alg.inventory_item_snapshot) + AND NOT EXISTS (SELECT 1 FROM alg.lane_state) +BEGIN + EXEC alg.usp_rebuild_space_topology; + EXEC alg.usp_sync_inventory_snapshot; + EXEC alg.usp_rebuild_lane_state; + DELETE FROM alg.dirty_lane_queue; +END; +MERGE alg.tidy_mode WITH (HOLDLOCK) AS target +USING (SELECT DISTINCT warehouse_id FROM alg.space_topology) AS source + ON target.warehouse_id = source.warehouse_id +WHEN NOT MATCHED THEN INSERT ( + warehouse_id, requested_enabled, effective_state, status_reason, mode_version, updated_at) + VALUES (source.warehouse_id, 0, 'NORMAL', 'MIGRATION_INITIALIZED', 0, SYSUTCDATETIME()); +MERGE alg.tidy_lane_queue WITH (HOLDLOCK) AS target +USING (SELECT warehouse_id, lane_code FROM alg.lane_state) AS source + ON target.warehouse_id = source.warehouse_id AND target.lane_code = source.lane_code +WHEN NOT MATCHED THEN INSERT ( + warehouse_id, lane_code, dirty_version, queue_status, reason_mask, change_count, last_dirty_at) + VALUES (source.warehouse_id, source.lane_code, 1, 'PENDING', 0, 1, SYSUTCDATETIME()); +GO diff --git a/fortucky-algorithm/src/main/resources/db/sqlserver/uninstall.sql b/fortucky-algorithm/src/main/resources/db/sqlserver/uninstall.sql new file mode 100644 index 0000000..b173938 --- /dev/null +++ b/fortucky-algorithm/src/main/resources/db/sqlserver/uninstall.sql @@ -0,0 +1,53 @@ +/* Removes only objects owned by schema alg. Run independently of install.sql. */ +SET NOCOUNT ON; + +IF OBJECT_ID(N'dbo.trg_alg_dirty_bas_stock', N'TR') IS NOT NULL DROP TRIGGER dbo.trg_alg_dirty_bas_stock; +IF OBJECT_ID(N'dbo.trg_alg_dirty_bas_cargo_space', N'TR') IS NOT NULL DROP TRIGGER dbo.trg_alg_dirty_bas_cargo_space; +IF OBJECT_ID(N'dbo.trg_alg_dirty_mydo_job', N'TR') IS NOT NULL DROP TRIGGER dbo.trg_alg_dirty_mydo_job; +IF OBJECT_ID(N'alg.trg_alg_dirty_space_role', N'TR') IS NOT NULL DROP TRIGGER alg.trg_alg_dirty_space_role; +IF OBJECT_ID(N'alg.trg_alg_dirty_project_policy', N'TR') IS NOT NULL DROP TRIGGER alg.trg_alg_dirty_project_policy; +IF OBJECT_ID(N'alg.trg_alg_dirty_warehouse_policy', N'TR') IS NOT NULL DROP TRIGGER alg.trg_alg_dirty_warehouse_policy; +GO +IF OBJECT_ID(N'alg.usp_refresh_dirty_lanes', N'P') IS NOT NULL DROP PROCEDURE alg.usp_refresh_dirty_lanes; +IF OBJECT_ID(N'alg.usp_mark_dirty_lane', N'P') IS NOT NULL DROP PROCEDURE alg.usp_mark_dirty_lane; +IF OBJECT_ID(N'alg.usp_claim_tidy_lane', N'P') IS NOT NULL DROP PROCEDURE alg.usp_claim_tidy_lane; +IF OBJECT_ID(N'alg.usp_release_tidy_lane', N'P') IS NOT NULL DROP PROCEDURE alg.usp_release_tidy_lane; +IF OBJECT_ID(N'alg.usp_complete_move_job', N'P') IS NOT NULL DROP PROCEDURE alg.usp_complete_move_job; +IF OBJECT_ID(N'alg.usp_sync_replay_sequences', N'P') IS NOT NULL DROP PROCEDURE alg.usp_sync_replay_sequences; +IF OBJECT_ID(N'alg.usp_release_reservation', N'P') IS NOT NULL DROP PROCEDURE alg.usp_release_reservation; +IF OBJECT_ID(N'alg.usp_try_reserve_inbound', N'P') IS NOT NULL DROP PROCEDURE alg.usp_try_reserve_inbound; +IF OBJECT_ID(N'alg.usp_apply_space_role', N'P') IS NOT NULL DROP PROCEDURE alg.usp_apply_space_role; +IF OBJECT_ID(N'alg.usp_release_deep_workflow_lock', N'P') IS NOT NULL DROP PROCEDURE alg.usp_release_deep_workflow_lock; +IF OBJECT_ID(N'alg.usp_acquire_deep_workflow_lock', N'P') IS NOT NULL DROP PROCEDURE alg.usp_acquire_deep_workflow_lock; +IF OBJECT_ID(N'alg.usp_rebuild_lane_state', N'P') IS NOT NULL DROP PROCEDURE alg.usp_rebuild_lane_state; +IF OBJECT_ID(N'alg.usp_compute_lane_semantic_fingerprint', N'P') IS NOT NULL DROP PROCEDURE alg.usp_compute_lane_semantic_fingerprint; +IF OBJECT_ID(N'alg.usp_sync_inventory_snapshot', N'P') IS NOT NULL DROP PROCEDURE alg.usp_sync_inventory_snapshot; +IF OBJECT_ID(N'alg.usp_rebuild_space_topology', N'P') IS NOT NULL DROP PROCEDURE alg.usp_rebuild_space_topology; +GO +IF OBJECT_ID(N'alg.v_space_state', N'V') IS NOT NULL DROP VIEW alg.v_space_state; +IF OBJECT_ID(N'alg.v_active_job', N'V') IS NOT NULL DROP VIEW alg.v_active_job; +IF OBJECT_ID(N'alg.v_inventory_item', N'V') IS NOT NULL DROP VIEW alg.v_inventory_item; +GO +IF OBJECT_ID(N'alg.outbound_workflow_space', N'U') IS NOT NULL DROP TABLE alg.outbound_workflow_space; +IF OBJECT_ID(N'alg.outbound_workflow_step', N'U') IS NOT NULL DROP TABLE alg.outbound_workflow_step; +IF OBJECT_ID(N'alg.outbound_workflow', N'U') IS NOT NULL DROP TABLE alg.outbound_workflow; +IF OBJECT_ID(N'alg.tidy_callback_event', N'U') IS NOT NULL DROP TABLE alg.tidy_callback_event; +IF OBJECT_ID(N'alg.tidy_space_lock', N'U') IS NOT NULL DROP TABLE alg.tidy_space_lock; +IF OBJECT_ID(N'alg.tidy_step', N'U') IS NOT NULL DROP TABLE alg.tidy_step; +IF OBJECT_ID(N'alg.tidy_workflow', N'U') IS NOT NULL DROP TABLE alg.tidy_workflow; +IF OBJECT_ID(N'alg.tidy_lane_queue', N'U') IS NOT NULL DROP TABLE alg.tidy_lane_queue; +IF OBJECT_ID(N'alg.tidy_mode', N'U') IS NOT NULL DROP TABLE alg.tidy_mode; +IF OBJECT_ID(N'alg.decision_log', N'U') IS NOT NULL DROP TABLE alg.decision_log; +IF OBJECT_ID(N'alg.deep_workflow_lock', N'U') IS NOT NULL DROP TABLE alg.deep_workflow_lock; +IF OBJECT_ID(N'alg.reservation', N'U') IS NOT NULL DROP TABLE alg.reservation; +IF OBJECT_ID(N'alg.dirty_lane_queue', N'U') IS NOT NULL DROP TABLE alg.dirty_lane_queue; +IF OBJECT_ID(N'alg.lane_state', N'U') IS NOT NULL DROP TABLE alg.lane_state; +IF OBJECT_ID(N'alg.space_inventory_summary', N'U') IS NOT NULL DROP TABLE alg.space_inventory_summary; +IF OBJECT_ID(N'alg.inventory_item_snapshot', N'U') IS NOT NULL DROP TABLE alg.inventory_item_snapshot; +IF OBJECT_ID(N'alg.space_topology', N'U') IS NOT NULL DROP TABLE alg.space_topology; +IF OBJECT_ID(N'alg.space_role', N'U') IS NOT NULL DROP TABLE alg.space_role; +IF OBJECT_ID(N'alg.project_policy', N'U') IS NOT NULL DROP TABLE alg.project_policy; +IF OBJECT_ID(N'alg.warehouse_policy', N'U') IS NOT NULL DROP TABLE alg.warehouse_policy; +GO +IF SCHEMA_ID(N'alg') IS NOT NULL EXEC(N'DROP SCHEMA alg'); +GO diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/LaneAnalyzerTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/LaneAnalyzerTest.java new file mode 100644 index 0000000..70bb02e --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/LaneAnalyzerTest.java @@ -0,0 +1,136 @@ +package com.ruoyi.algorithm; + +import com.ruoyi.algorithm.model.LaneState; +import com.ruoyi.algorithm.model.SpaceRole; +import com.ruoyi.algorithm.model.SpaceState; +import com.ruoyi.algorithm.model.SpaceStatus; +import com.ruoyi.algorithm.policy.SchedulingPolicy; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class LaneAnalyzerTest { + + private final LaneAnalyzer analyzer = new LaneAnalyzer(); + + @Test + void findsNextSlotFromInsideToOutside() { + LaneState lane = analyzer.analyze(List.of( + space("S1", 1, SpaceStatus.OCCUPIED, "T1", "P1"), + space("S2", 2, SpaceStatus.OCCUPIED, "T2", "P1"), + space("S3", 3, SpaceStatus.EMPTY, null, null), + space("S4", 4, SpaceStatus.EMPTY, null, null), + space("S5", 5, SpaceStatus.EMPTY, null, null) + ), SchedulingPolicy.ft546Defaults()); + + assertThat(lane.physicallyContinuous()).isTrue(); + assertThat(lane.nextSlot()).isPresent(); + assertThat(lane.nextSlot().orElseThrow().spaceId()).isEqualTo("S3"); + assertThat(lane.residentProjectNo()).contains("P1"); + assertThat(lane.segmentCount()).isEqualTo(1); + } + + @Test + void detectsInnerHoleAndRefusesNextSlot() { + LaneState lane = analyzer.analyze(List.of( + space("S1", 1, SpaceStatus.OCCUPIED, "T1", "P1"), + space("S2", 2, SpaceStatus.EMPTY, null, null), + space("S3", 3, SpaceStatus.OCCUPIED, "T3", "P1") + ), SchedulingPolicy.ft546Defaults()); + + assertThat(lane.physicallyContinuous()).isFalse(); + assertThat(lane.nextSlot()).isEmpty(); + } + + @Test + void detectsResidentAndSingleOuterGuestSegments() { + LaneState lane = analyzer.analyze(List.of( + space("S1", 1, SpaceStatus.OCCUPIED, "T1", "P1"), + space("S2", 2, SpaceStatus.OCCUPIED, "T2", "P1"), + space("S3", 3, SpaceStatus.OCCUPIED, "T3", "P2"), + space("S4", 4, SpaceStatus.EMPTY, null, null) + ), SchedulingPolicy.ft546Defaults()); + + assertThat(lane.segmentCount()).isEqualTo(2); + assertThat(lane.residentProjectNo()).contains("P1"); + assertThat(lane.guestProjectNo()).contains("P2"); + assertThat(lane.corrupt()).isFalse(); + assertThat(lane.outerSlot().orElseThrow().spaceId()).isEqualTo("S4"); + } + + @Test + void outerSlotIsTheFirstEmptyPositionImmediatelyOutsideStock() { + LaneState lane = analyzer.analyze(List.of( + space("S1", 1, SpaceStatus.OCCUPIED, "T1", "P1"), + space("S2", 2, SpaceStatus.OCCUPIED, "T2", "P1"), + space("S3", 3, SpaceStatus.EMPTY, null, null), + space("S4", 4, SpaceStatus.EMPTY, null, null), + space("S5", 5, SpaceStatus.EMPTY, null, null) + ), SchedulingPolicy.ft546Defaults()); + + assertThat(lane.outerSlot()).isPresent(); + assertThat(lane.outerSlot().orElseThrow().spaceId()).isEqualTo("S3"); + } + + @Test + void marksThreeProjectSegmentsCorrupt() { + LaneState lane = analyzer.analyze(List.of( + space("S1", 1, SpaceStatus.OCCUPIED, "T1", "P1"), + space("S2", 2, SpaceStatus.OCCUPIED, "T2", "P2"), + space("S3", 3, SpaceStatus.OCCUPIED, "T3", "P1") + ), SchedulingPolicy.ft546Defaults()); + + assertThat(lane.segmentCount()).isEqualTo(3); + assertThat(lane.corrupt()).isTrue(); + } + + @Test + void marksAggregatedMultiProjectInventoryCorrupt() { + LaneState lane = analyzer.analyze(List.of( + space("S1", 1, SpaceStatus.OCCUPIED, "T1", "P1", true), + space("S2", 2, SpaceStatus.EMPTY, null, null) + ), SchedulingPolicy.ft546Defaults()); + + assertThat(lane.corrupt()).isTrue(); + assertThat(lane.nextSlot()).isEmpty(); + } + + @Test + void marksEmptyStatusWithTrayCorruptInsteadOfAllocatable() { + LaneState lane = analyzer.analyze(List.of( + space("S1", 1, SpaceStatus.EMPTY, "T1", "P1"), + space("S2", 2, SpaceStatus.EMPTY, null, null) + ), SchedulingPolicy.ft546Defaults()); + + assertThat(lane.corrupt()).isTrue(); + assertThat(lane.nextSlot()).isEmpty(); + } + + @Test + void countsOccupiedInventoryWithUnknownProjectAsASegment() { + LaneState lane = analyzer.analyze(List.of( + space("S1", 1, SpaceStatus.OCCUPIED, "T1", null), + space("S2", 2, SpaceStatus.OCCUPIED, "T2", "P1"), + space("S3", 3, SpaceStatus.EMPTY, null, null) + ), SchedulingPolicy.ft546Defaults()); + + assertThat(lane.segmentCount()).isEqualTo(2); + assertThat(lane.residentProjectNo()).isEmpty(); + assertThat(lane.guestProjectNo()).contains("P1"); + } + + private SpaceState space(String id, int depthOrder, SpaceStatus status, String tray, String project) { + return space(id, depthOrder, status, tray, project, false); + } + + private SpaceState space(String id, int depthOrder, SpaceStatus status, String tray, String project, + boolean inventoryProjectConflict) { + return new SpaceState( + id, "01", "L1", depthOrder, 5, 1, 7, depthOrder, "A", + SpaceRole.STORAGE, status, false, inventoryProjectConflict, tray, project, null, null, + null, null, false, null + ); + } +} diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/SchedulingPolicyTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/SchedulingPolicyTest.java new file mode 100644 index 0000000..ab9c647 --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/SchedulingPolicyTest.java @@ -0,0 +1,23 @@ +package com.ruoyi.algorithm; + +import com.ruoyi.algorithm.policy.SchedulingPolicy; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class SchedulingPolicyTest { + + @Test + void ft546DefaultsMatchTheKnownJavascriptPolicy() { + SchedulingPolicy policy = SchedulingPolicy.ft546Defaults(); + + assertThat(policy.capacityWeight()).isEqualTo(0.55); + assertThat(policy.efficiencyWeight()).isEqualTo(0.45); + assertThat(policy.warningOccupied()).isEqualTo(564); + assertThat(policy.capacityFirstOccupied()).isEqualTo(597); + assertThat(policy.maxOccupied()).isEqualTo(615); + assertThat(policy.relocationBuffersPerFloor()).isEqualTo(4); + assertThat(policy.outboundCachesPerFloor()).isEqualTo(2); + assertThat(policy.maxTidyCandidates()).isEqualTo(10); + } +} diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/contract/JsAlgorithmContractTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/contract/JsAlgorithmContractTest.java new file mode 100644 index 0000000..58c26ba --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/contract/JsAlgorithmContractTest.java @@ -0,0 +1,137 @@ +package com.ruoyi.algorithm.contract; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.algorithm.inbound.BatchLaneMode; +import com.ruoyi.algorithm.inbound.InboundContext; +import com.ruoyi.algorithm.inbound.InboundPlanner; +import com.ruoyi.algorithm.inbound.InboundPolicy; +import com.ruoyi.algorithm.inbound.InboundRequest; +import com.ruoyi.algorithm.model.SpaceRole; +import com.ruoyi.algorithm.model.SpaceState; +import com.ruoyi.algorithm.model.SpaceStatus; +import com.ruoyi.algorithm.outbound.OutboundCapacityMode; +import com.ruoyi.algorithm.outbound.OutboundContext; +import com.ruoyi.algorithm.outbound.OutboundPlanner; +import com.ruoyi.algorithm.outbound.OutboundRequest; +import com.ruoyi.algorithm.policy.SchedulingPolicy; +import org.junit.jupiter.api.Test; + +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HexFormat; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class JsAlgorithmContractTest { + private final ObjectMapper mapper = new ObjectMapper(); + + @Test + void generatedFixturesMatchTheExactJavascriptSourceAndJavaDecisions() throws Exception { + try (InputStream stream = getClass().getResourceAsStream("/contracts/js-contract-fixtures.json")) { + assertThat(stream).as("run tools/export-js-contracts.js first").isNotNull(); + JsonNode root = mapper.readTree(stream); + assertThat(root.path("sourceAlgorithmVersion").asText()).isEqualTo("1.2.0"); + Path source = Path.of("..", "..", "..", "ft546-storage-scheduling-algorithm.js"); + assertThat(root.path("sourceSha256").asText()).isEqualTo(sha256(Files.readAllBytes(source))); + assertThat(root.path("fixtures")).hasSize(4); + for (JsonNode fixture : root.path("fixtures")) { + verifyFixture(fixture); + } + } + } + + private void verifyFixture(JsonNode fixture) { + List spaces = new ArrayList<>(); + Map inboundTimes = new LinkedHashMap<>(); + for (JsonNode node : fixture.path("spaces")) { + assertThat(node.has("isCacheCore")).isTrue(); + assertThat(node.has("isReserveCore")).isTrue(); + String expectedRole = node.path("isCacheCore").asBoolean() ? "OUTBOUND_CACHE" + : node.path("isReserveCore").asBoolean() ? "PROTECTED_CORE" : "STORAGE"; + assertThat(node.path("role").asText()).isEqualTo(expectedRole); + String inbound = text(node, "inboundAt"); + SpaceState space = new SpaceState(text(node, "spaceId"), text(node, "zoneCode"), + text(node, "laneCode"), node.path("depthOrder").asInt(), node.path("laneCapacity").asInt(), + node.path("floorNo").asInt(), node.path("aisleNo").asInt(), node.path("groupCoding").asInt(), + text(node, "rowCode"), SpaceRole.valueOf(node.path("role").asText()), + SpaceStatus.valueOf(node.path("status").asText()), node.path("outboundTaskActive").asBoolean(), + false, text(node, "trayNo"), text(node, "projectNo"), text(node, "productId"), + text(node, "lotNo"), inbound == null ? null : Instant.parse(inbound), null, false, null); + spaces.add(space); + if (inbound != null) inboundTimes.put(space.spaceId(), inbound); + } + SchedulingPolicy scheduling = new SchedulingPolicy(fixture.at("/policy/capacityWeight").asDouble(), + fixture.at("/policy/efficiencyWeight").asDouble(), 564, 597, 615, 4, 2, 10); + JsonNode request = fixture.path("request"); + JsonNode expected = fixture.path("expected"); + assertThat(expected.path("planStatus").asText()).isEqualTo("READY"); + assertThat(expected.path("taskPlanCount").asInt()).isOne(); + assertThat(expected.path("plannedCount").asInt()).isOne(); + assertThat(expected.path("rejectedCount").asInt()).isZero(); + assertThat(expected.path("executionState").asText()).isIn("READY", "READY_WITH_ELEVATOR_TOKEN"); + if ("INBOUND".equals(fixture.path("kind").asText())) { + InboundRequest value = new InboundRequest(text(request, "requestId"), text(request, "trayNo"), + text(request, "projectNo"), text(request, "productId"), text(request, "lotNo"), + nullableInt(request, "expectedProjectPallets"), nullableInt(request, "entryFloor"), + nullableInt(request, "targetFloor"), Set.of(), BatchLaneMode.valueOf(request.path("batchLaneMode").asText())); + var plan = new InboundPlanner().plan(value, new InboundContext(spaces, + new InboundPolicy(scheduling, Set.of(), Set.of("COMMON"), List.of(), 0), List.of(), + (int) spaces.stream().filter(SpaceState::occupied).count())); + var assignment = plan.assignment().orElseThrow(); + assertThat(assignment.spaceId()).as(fixture.path("id").asText()).isEqualTo(text(expected, "spaceId")); + assertThat(assignment.laneCode()).isEqualTo(text(expected, "laneCode")); + assertThat(assignment.ladderRung().name()).isEqualTo(text(expected, "ladderRung")); + assertThat(assignment.capacityScore()).isEqualTo(expected.path("capacityScore").asDouble()); + assertThat(assignment.efficiencyScore()).isEqualTo(expected.path("efficiencyScore").asDouble()); + assertThat(assignment.totalScore()).isEqualTo(expected.path("totalScore").asDouble()); + assertThat(assignment.openedNewLane()).isEqualTo(expected.path("openedNewLane").asBoolean()); + } else { + OutboundRequest value = new OutboundRequest(text(request, "requestId"), text(request, "trayNo"), + text(request, "projectNo"), text(request, "productId"), text(request, "fifoMode"), + nullableInt(request, "fifoToleranceMinutes"), nullableInt(request, "exitFloor"), true); + var plan = new OutboundPlanner().plan(value, + new OutboundContext(spaces, inboundTimes, OutboundCapacityMode.BALANCED)); + var assignment = plan.assignment().orElseThrow(); + assertThat(plan.status().name()).isEqualTo(expected.path("planStatus").asText()); + assertThat(assignment.trayNo()).as(fixture.path("id").asText()).isEqualTo(text(expected, "trayNo")); + assertThat(assignment.sourceSpaceId()).isEqualTo(text(expected, "sourceSpaceId")); + assertThat(assignment.fifo().fifoRank()).isEqualTo(expected.path("fifoRank").asInt()); + assertThat(assignment.fifo().fifoViolation()).isEqualTo(expected.path("fifoViolation").asBoolean()); + assertThat(assignment.fifo().fifoMode()).isEqualTo(text(expected, "fifoMode")); + assertThat(assignment.fifo().fifoDeviationMinutes()) + .isEqualTo(expected.path("fifoDeviationMinutes").asInt()); + assertThat(assignment.blockerSpaceIds()).isEqualTo(mapper.convertValue( + expected.path("blockerSpaceIds"), mapper.getTypeFactory().constructCollectionType(List.class, String.class))); + assertThat(assignment.blockingTrayNos()).isEqualTo(mapper.convertValue( + expected.path("blockingTrayNos"), mapper.getTypeFactory().constructCollectionType(List.class, String.class))); + assertThat(assignment.blockerSpaceIds()).hasSize(expected.path("blockerCount").asInt()); + assertThat(assignment.capacityScore()).isEqualTo(expected.path("capacityScore").asDouble()); + assertThat(assignment.efficiencyScore()).isEqualTo(expected.path("efficiencyScore").asDouble()); + assertThat(assignment.totalScore()).isEqualTo(expected.path("totalScore").asDouble()); + assertThat(plan.taskCountEstimate().outbound()).isEqualTo(expected.path("taskPlanCount").asInt()); + } + } + + private String text(JsonNode node, String field) { + JsonNode value = node.get(field); + return value == null || value.isNull() || value.asText().isBlank() ? null : value.asText(); + } + + private Integer nullableInt(JsonNode node, String field) { + JsonNode value = node.get(field); + return value == null || value.isNull() ? null : value.asInt(); + } + + private String sha256(byte[] value) throws Exception { + return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(value)); + } +} diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/inbound/InboundPlannerTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/inbound/InboundPlannerTest.java new file mode 100644 index 0000000..ec367a0 --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/inbound/InboundPlannerTest.java @@ -0,0 +1,453 @@ +package com.ruoyi.algorithm.inbound; + +import com.ruoyi.algorithm.model.SpaceRole; +import com.ruoyi.algorithm.model.SpaceState; +import com.ruoyi.algorithm.model.SpaceStatus; +import com.ruoyi.algorithm.policy.SchedulingPolicy; +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class InboundPlannerTest { + + private final InboundPlanner planner = new InboundPlanner(); + + @Test + void continuesFromInsideToOutsideAndProtectsTheWholeLaneFromOutboundWork() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("SAFE", 5, "MAIN", occupied(1, "P1"), occupied(2, "P1"), empty(3), empty(4), empty(5))); + spaces.addAll(lane("BLOCKED", 5, "MAIN", occupied(1, "P1"), outboundEmpty(2), empty(3), empty(4), empty(5))); + + InboundPlan plan = plan(request("P1"), spaces); + + assertThat(plan.assignment()).isPresent(); + assertThat(plan.assignment().orElseThrow().laneCode()).isEqualTo("SAFE"); + assertThat(plan.assignment().orElseThrow().spaceId()).isEqualTo("SAFE-3"); + assertThat(plan.assignment().orElseThrow().ladderRung()).isEqualTo(InboundLadderRung.CONTINUE); + } + + @Test + void rejectsDiscontinuousLaneAndOnlyRejectsAfterEveryLegalSlotIsExhausted() { + List spaces = lane("HOLE", 5, "MAIN", + occupied(1, "P1"), empty(2), occupied(3, "P1"), empty(4), empty(5)); + + InboundPlan plan = plan(request("P1"), spaces); + + assertThat(plan.rejection()).isPresent(); + assertThat(plan.rejection().orElseThrow().code()).isEqualTo(InboundRejectionCode.NO_FEASIBLE_LOCATION); + assertThat(plan.rejection().orElseThrow().reason()).contains("exhausted"); + assertThat(plan.rejection().orElseThrow().ladderTrace()).extracting(LadderTraceStep::rung) + .containsExactly(InboundLadderRung.CONTINUE, InboundLadderRung.OPEN_GRADED, + InboundLadderRung.OPEN_ADJACENT, InboundLadderRung.MIXED_GUEST, + InboundLadderRung.POOL_BORROW); + } + + @Test + void rejectsIncompleteLaneTopologyInsteadOfTreatingItAsContinuous() { + List partial = List.of( + space("PARTIAL", 5, "MAIN", 1, 6, "1", occupied(2, "P1")), + space("PARTIAL", 5, "MAIN", 1, 6, "1", empty(3))); + + InboundPlan plan = plan(request("P1"), partial); + + assertThat(plan.assignment()).isEmpty(); + assertThat(plan.rejection().orElseThrow().code()).isEqualTo(InboundRejectionCode.NO_FEASIBLE_LOCATION); + } + + @Test + void guestContinuesOnlyInTheOuterSegmentWhileResidentCannotBuryIt() { + List shared = lane("SHARED", 5, "MAIN", + occupied(1, "HOST"), occupied(2, "HOST"), occupied(3, "GUEST"), empty(4), empty(5)); + + InboundPlan guest = plan(request("GUEST"), shared); + InboundPlan resident = plan(request("HOST"), shared); + + assertThat(guest.assignment()).isPresent(); + assertThat(guest.assignment().orElseThrow().spaceId()).isEqualTo("SHARED-4"); + assertThat(guest.assignment().orElseThrow().borrowType()).isEqualTo(InboundBorrowType.MIXED_IN); + assertThat(resident.assignment()).isEmpty(); + } + + @Test + void gradedDepthUsesExpectationThenIncubationFallback() { + List spaces = new ArrayList<>(); + spaces.addAll(emptyLane("D2", 2, "MAIN")); + spaces.addAll(emptyLane("D3", 3, "MAIN")); + spaces.addAll(emptyLane("D5", 5, "MAIN")); + + assertThat(plan(request("P", 2), spaces).assignment().orElseThrow().laneCapacity()).isEqualTo(2); + assertThat(plan(request("P", 3), spaces).assignment().orElseThrow().laneCapacity()).isEqualTo(3); + assertThat(plan(request("P", 4), spaces).assignment().orElseThrow().laneCapacity()).isEqualTo(5); + + List onePallet = new ArrayList<>(spaces); + onePallet.add(single("OLD", "MAIN", SpaceStatus.OCCUPIED, "P", "M", "B", false)); + assertThat(plan(request("P"), onePallet).assignment().orElseThrow().laneCapacity()).isEqualTo(2); + + List twoPallets = new ArrayList<>(onePallet); + twoPallets.add(single("OLD2", "MAIN", SpaceStatus.OCCUPIED, "P", "M", "B", false)); + assertThat(plan(request("P"), twoPallets).assignment().orElseThrow().laneCapacity()).isEqualTo(5); + } + + @Test + void smallProjectPrefersSinglePoolBeforeAdjacentDepth() { + List spaces = new ArrayList<>(); + spaces.add(single("SINGLE", "FLEX", SpaceStatus.EMPTY, null, null, null, false)); + spaces.addAll(emptyLane("D3", 3, "MAIN")); + + InboundAssignment assignment = plan(request("SMALL", 2), spaces).assignment().orElseThrow(); + + assertThat(assignment.spaceId()).isEqualTo("SINGLE"); + assertThat(assignment.ladderRung()).isEqualTo(InboundLadderRung.POOL_BORROW); + } + + @Test + void adjacentDepthOrderIsDeterministicForEachTargetGrade() { + assertThat(plan(request("P2", 2), lanesOfDepths(3, 5)).assignment().orElseThrow().laneCapacity()).isEqualTo(3); + assertThat(plan(request("P3", 3), lanesOfDepths(2, 5)).assignment().orElseThrow().laneCapacity()).isEqualTo(5); + assertThat(plan(request("P5", 5), lanesOfDepths(2, 3)).assignment().orElseThrow().laneCapacity()).isEqualTo(3); + } + + @Test + void mixedGuestAllowsOnlyOneGuestRejectsIsolationBothWaysAndExcludesPendingResidents() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("PENDING", 5, "MAIN", occupied(1, "A"), occupied(2, "A"), occupied(3, "A"), occupied(4, "A"), empty(5))); + spaces.addAll(lane("OPEN", 5, "MAIN", occupied(1, "B"), occupied(2, "B"), occupied(3, "B"), occupied(4, "B"), empty(5))); + InboundContext context = context(spaces, policy(Set.of("ISO"), Set.of("COMMON"), List.of(), 0), + List.of(new PendingOutbound("A", null, null))); + + assertThat(planner.plan(request("C"), context).assignment().orElseThrow().laneCode()).isEqualTo("OPEN"); + + List withGuest = lane("TWO", 5, "MAIN", occupied(1, "A"), occupied(2, "G"), empty(3), empty(4), empty(5)); + assertThat(plan(request("THIRD"), withGuest).assignment()).isEmpty(); + assertThat(planner.plan(request("ISO"), context).assignment()).isEmpty(); + + List isolatedResident = lane("ISO-LANE", 5, "MAIN", + occupied(1, "ISO"), occupied(2, "ISO"), occupied(3, "ISO"), occupied(4, "ISO"), empty(5)); + assertThat(planner.plan(request("NORMAL"), context(isolatedResident, + policy(Set.of("ISO"), Set.of("COMMON"), List.of(), 0), List.of())).assignment()).isEmpty(); + } + + @Test + void mixedGuestRequiresBothProjectsToAllowMixing() { + List residentLane = lane("MIX-POLICY", 5, "MAIN", + occupied(1, "RESIDENT"), occupied(2, "RESIDENT"), occupied(3, "RESIDENT"), + occupied(4, "RESIDENT"), empty(5)); + InboundPolicy deniedIncoming = new InboundPolicy(SchedulingPolicy.ft546Defaults(), Set.of(), + Set.of("COMMON"), List.of(), 0, Set.of("INCOMING")); + InboundPolicy deniedResident = new InboundPolicy(SchedulingPolicy.ft546Defaults(), Set.of(), + Set.of("COMMON"), List.of(), 0, Set.of("RESIDENT")); + + assertThat(planner.plan(request("INCOMING"), context(residentLane, deniedIncoming, List.of())).assignment()) + .isEmpty(); + assertThat(planner.plan(request("INCOMING"), context(residentLane, deniedResident, List.of())).assignment()) + .isEmpty(); + assertThat(planner.plan(request("INCOMING"), context(residentLane, InboundPolicy.defaults(), List.of())) + .assignment()).isPresent(); + } + + @Test + void pendingOutboundBlocksOnlyExactTrayOrResolvedLaneAndUnresolvedScopeIsSafe() { + List lane = lane("PENDING-MATCH", 5, "MAIN", + occupied(1, "P"), empty(2), empty(3), empty(4), empty(5)); + InboundPolicy policy = InboundPolicy.defaults(); + + assertThat(planner.plan(request("P"), context(lane, policy, + List.of(new PendingOutbound("OTHER", "OTHER", "PENDING-MATCH-T1")))).assignment()).isEmpty(); + assertThat(planner.plan(request("P"), context(lane, policy, + List.of(new PendingOutbound("P", "M", null)))).assignment()).isPresent(); + assertThat(planner.plan(request("P"), context(lane, policy, + List.of(new PendingOutbound("P", null, null)))).assignment()).isPresent(); + assertThat(planner.plan(request("P"), context(lane, policy, + List.of(new PendingOutbound("OTHER", null, null, "PENDING-MATCH", "EXPLICIT")))) + .assignment()).isEmpty(); + assertThat(planner.plan(request("P"), context(lane, policy, + List.of(new PendingOutbound("OTHER", null, "NOT-THE-TRAY", "PENDING-MATCH", "EXPLICIT")))) + .assignment()).isEmpty(); + + assertThat(planner.plan(request("P"), context(lane, policy, + List.of(new PendingOutbound("P", "OTHER", null)))).assignment()).isPresent(); + assertThat(planner.plan(request("P"), context(lane, policy, + List.of(new PendingOutbound("P", "M", "NOT-THE-TRAY")))).assignment()).isPresent(); + } + + @Test + void continuationNeverSkipsAnUnavailablePhysicalNextDepth() { + List reservedLane = lane("RESERVED-NEXT", 5, "MAIN", + occupied(1, "P"), empty(2), empty(3), empty(4), empty(5)); + reservedLane.set(1, withReserved(reservedLane.get(1))); + List roleLane = lane("ROLE-NEXT", 5, "MAIN", + occupied(1, "P"), empty(2), empty(3), empty(4), empty(5)); + roleLane.set(1, withRole(roleLane.get(1), SpaceRole.RELOCATION_BUFFER)); + List disabledLane = lane("DISABLED-NEXT", 5, "MAIN", + occupied(1, "P"), empty(2), empty(3), empty(4), empty(5)); + disabledLane.set(1, withStatus(disabledLane.get(1), SpaceStatus.DISABLED)); + List spaces = new ArrayList<>(); + spaces.addAll(reservedLane); + spaces.addAll(roleLane); + spaces.addAll(disabledLane); + + assertThat(plan(request("P"), spaces).assignment()).isEmpty(); + } + + @Test + void poolWatermarkAndFlexCacheReserveTiersAreEnforced() { + List tiers = List.of( + single("FLEX", "FLEX", SpaceStatus.EMPTY, null, null, null, false), + single("CACHE", "CACHE", SpaceStatus.EMPTY, null, null, null, false), + single("RESERVE", "RESERVE", SpaceStatus.EMPTY, null, null, null, false)); + + assertThat(plan(request("P", 5), tiers).assignment().orElseThrow().spaceId()).isEqualTo("FLEX"); + List noFlex = tiers.stream().filter(space -> !space.spaceId().equals("FLEX")).toList(); + assertThat(plan(request("P", 5), noFlex).assignment().orElseThrow().borrowType()).isEqualTo(InboundBorrowType.CACHE_BORROWED); + + InboundContext belowHighWater = context(List.of(tiers.get(2)), policy(Set.of(), Set.of("COMMON"), List.of(), 0), List.of()); + assertThat(planner.plan(request("P", 5), belowHighWater).assignment()).isEmpty(); + InboundContext atHighWater = new InboundContext(List.of(tiers.get(2)), + policy(Set.of(), Set.of("COMMON"), List.of(), 0), List.of(), 597); + assertThat(planner.plan(request("P", 5), atHighWater).assignment().orElseThrow().borrowType()) + .isEqualTo(InboundBorrowType.RESERVE_BORROWED); + + InboundContext guarded = context(List.of(tiers.get(0)), policy(Set.of(), Set.of("COMMON"), List.of(), 1), List.of()); + assertThat(planner.plan(request("P", 5), guarded).rejection().orElseThrow().ladderTrace()) + .anySatisfy(step -> assertThat(step.reason()).contains("watermark")); + } + + @Test + void zeroPoolReserveWithoutSingleSlotsReportsAvailabilityInsteadOfWatermark() { + InboundPlan plan = planner.plan(request("P", 5), + context(List.of(), policy(Set.of(), Set.of("COMMON"), List.of(), 0), List.of())); + + assertThat(plan.rejection().orElseThrow().ladderTrace()) + .filteredOn(step -> step.rung() == InboundLadderRung.POOL_BORROW) + .singleElement() + .satisfies(step -> { + assertThat(step.reason()).contains("No legal"); + assertThat(step.reason()).doesNotContain("watermark"); + }); + } + + @Test + void commonPartsUseSingleTiersThenSameMaterialDoubleLane() { + List spaces = new ArrayList<>(); + spaces.add(single("CACHE", "CACHE", SpaceStatus.EMPTY, null, null, null, false)); + spaces.addAll(laneWithProduct("DOUBLE", 2, "MAIN", "COMMON", "M1", null, empty(2))); + InboundPolicy commonPolicy = policy(Set.of(), Set.of("COMMON"), List.of(), 0); + + assertThat(planner.plan(request("COMMON", "M1", "B", null, BatchLaneMode.OPEN), + context(spaces, commonPolicy, List.of())).assignment().orElseThrow().spaceId()).isEqualTo("CACHE"); + + List doublesOnly = spaces.stream().filter(space -> !space.spaceId().equals("CACHE")).toList(); + assertThat(planner.plan(request("COMMON", "M1", "B", null, BatchLaneMode.OPEN), + context(doublesOnly, commonPolicy, List.of())).assignment().orElseThrow().spaceId()).isEqualTo("DOUBLE-2"); + assertThat(planner.plan(request("COMMON", "OTHER", "B", null, BatchLaneMode.OPEN), + context(doublesOnly, commonPolicy, List.of())).assignment()).isEmpty(); + } + + @Test + void manualReservationsRestrictLaneOwnership() { + List lane = emptyLane("VIP", 5, "MAIN"); + List named = List.of(new ManualLaneReservation("VIP", "P-VIP")); + InboundPolicy namedPolicy = policy(Set.of(), Set.of("COMMON"), named, 0); + + assertThat(planner.plan(request("OTHER", 5), context(lane, namedPolicy, List.of())).assignment()).isEmpty(); + assertThat(planner.plan(request("P-VIP", 5), context(lane, namedPolicy, List.of())).assignment()).isPresent(); + + InboundPolicy isolatedOnly = policy(Set.of("ISO"), Set.of("COMMON"), + List.of(new ManualLaneReservation("VIP", null)), 0); + assertThat(planner.plan(request("ISO", 5), context(lane, isolatedOnly, List.of())).assignment()).isPresent(); + assertThat(planner.plan(request("OTHER", 5), context(lane, isolatedOnly, List.of())).assignment()).isEmpty(); + } + + @Test + void rejectsUnknownManualReservationLane() { + InboundPolicy policy = policy(Set.of(), Set.of("COMMON"), + List.of(new ManualLaneReservation("MISSING", "P")), 0); + + org.assertj.core.api.Assertions.assertThatThrownBy(() -> + planner.plan(request("P", 5), context(emptyLane("REAL", 5, "MAIN"), policy, List.of()))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("MISSING"); + } + + @Test + void protectedReservedAndWrongFloorSlotsStayInvisibleAcrossTheLadder() { + SpaceState reserved = withReserved(single("RESERVED", "FLEX", SpaceStatus.EMPTY, + null, null, null, false)); + SpaceState relocation = withRole(single("RELOC", "FLEX", SpaceStatus.EMPTY, + null, null, null, false), SpaceRole.RELOCATION_BUFFER); + List spaces = new ArrayList<>(List.of(reserved, relocation)); + spaces.addAll(emptyLane("FLOOR-2", 5, "MAIN", 2, 6, "1")); + spaces.addAll(emptyLane("FLOOR-3", 5, "MAIN", 3, 6, "1")); + InboundRequest floorTwo = new InboundRequest("REQ", "TRAY", "P", "M", "B", + 5, 1, null, Set.of(2), BatchLaneMode.OPEN); + + assertThat(plan(floorTwo, spaces).assignment().orElseThrow().laneCode()).isEqualTo("FLOOR-2"); + } + + @Test + void sealedModeContinuesOnlyExactCohortOrOpensCompletelyEmptyLane() { + List spaces = new ArrayList<>(); + spaces.addAll(laneWithProduct("WRONG", 5, "MAIN", "P", "M", "OLD", empty(2), empty(3), empty(4), empty(5))); + spaces.addAll(laneWithProduct("EXACT", 5, "MAIN", "P", "M", "B1", empty(2), empty(3), empty(4), empty(5))); + + InboundAssignment exact = plan(request("P", "M", "B1", 5, BatchLaneMode.SEALED), spaces).assignment().orElseThrow(); + assertThat(exact.laneCode()).isEqualTo("EXACT"); + assertThat(exact.openedNewLane()).isFalse(); + + InboundPlan rejected = plan(request("P", "M", "B2", 5, BatchLaneMode.SEALED), + spaces.stream().filter(space -> space.laneCode().equals("WRONG")).toList()); + assertThat(rejected.rejection().orElseThrow().code()).isEqualTo(InboundRejectionCode.NO_BATCH_COMPATIBLE_LANE); + assertThat(rejected.rejection().orElseThrow().reason()).contains("same project, product and lot"); + assertThat(rejected.rejection().orElseThrow().ladderTrace()).isNotEmpty(); + } + + @Test + void commonSealedDoubleLaneIgnoresLotAndUsesNormalNoFeasibleRejection() { + List compatible = laneWithProduct("COMMON-DOUBLE", 2, "MAIN", + "COMMON", "M1", "OLD-LOT", empty(2)); + InboundRequest sealedNewLot = request("COMMON", "M1", "NEW-LOT", null, BatchLaneMode.SEALED); + + InboundPlan continued = plan(sealedNewLot, compatible); + + assertThat(continued.assignment()).isPresent(); + assertThat(continued.assignment().orElseThrow().ladderRung()) + .isEqualTo(InboundLadderRung.COMMON_LANE_CONTINUE); + + List incompatible = laneWithProduct("COMMON-OTHER", 2, "MAIN", + "COMMON", "OTHER", "OLD-LOT", empty(2)); + InboundPlan rejected = plan(sealedNewLot, incompatible); + assertThat(rejected.rejection().orElseThrow().code()) + .isEqualTo(InboundRejectionCode.NO_FEASIBLE_LOCATION); + } + + @Test + void scoringAndTieBreakMatchJavascriptFormula() { + List spaces = new ArrayList<>(); + spaces.addAll(emptyLane("B", 2, "MAIN", 1, 6, "1")); + spaces.addAll(emptyLane("A", 2, "MAIN", 1, 6, "1")); + + InboundAssignment assignment = plan(request("P", 2), spaces).assignment().orElseThrow(); + + assertThat(assignment.laneCode()).isEqualTo("A"); + assertThat(assignment.capacityScore()).isEqualTo(43.0); + assertThat(assignment.efficiencyScore()).isEqualTo(100.0); + assertThat(assignment.totalScore()).isEqualTo(68.7); + } + + private InboundPlan plan(InboundRequest request, List spaces) { + return planner.plan(request, context(spaces, InboundPolicy.defaults(), List.of())); + } + + private InboundRequest request(String project) { + return request(project, "M", "B", null, BatchLaneMode.OPEN); + } + + private InboundRequest request(String project, Integer expected) { + return request(project, "M", "B", expected, BatchLaneMode.OPEN); + } + + private InboundRequest request(String project, String product, String lot, Integer expected, BatchLaneMode mode) { + return new InboundRequest("REQ", "TRAY", project, product, lot, expected, 1, null, Set.of(), mode); + } + + private InboundContext context(List spaces, InboundPolicy policy, List pending) { + return new InboundContext(spaces, policy, pending, (int) spaces.stream().filter(SpaceState::occupied).count()); + } + + private InboundPolicy policy(Set isolated, Set common, + List reservations, int reserve) { + return new InboundPolicy(SchedulingPolicy.ft546Defaults(), isolated, common, reservations, reserve); + } + + private List lanesOfDepths(int... depths) { + List spaces = new ArrayList<>(); + for (int depth : depths) spaces.addAll(emptyLane("D" + depth, depth, "MAIN")); + return spaces; + } + + private List emptyLane(String code, int depth, String zone) { + return emptyLane(code, depth, zone, 1, 6, "1"); + } + + private List emptyLane(String code, int depth, String zone, int floor, int aisle, String row) { + List spaces = new ArrayList<>(); + for (int i = 1; i <= depth; i++) { + spaces.add(space(code, depth, zone, floor, aisle, row, empty(i))); + } + return spaces; + } + + private List lane(String code, int depth, String zone, Slot... slots) { + List spaces = new ArrayList<>(); + for (Slot slot : slots) spaces.add(space(code, depth, zone, 1, 6, "1", slot)); + return spaces; + } + + private List laneWithProduct(String code, int depth, String zone, String project, + String product, String lot, Slot... remainder) { + List slots = new ArrayList<>(); + slots.add(new Slot(1, SpaceStatus.OCCUPIED, project, product, lot, false)); + slots.addAll(List.of(remainder)); + return lane(code, depth, zone, slots.toArray(Slot[]::new)); + } + + private SpaceState single(String id, String zone, SpaceStatus status, String project, + String product, String lot, boolean outbound) { + return new SpaceState(id, zone, id, 1, 1, 1, 6, 1, "1", SpaceRole.STORAGE, + status, outbound, false, status == SpaceStatus.OCCUPIED ? "T-" + id : null, + project, product, lot, Instant.parse("2026-07-01T00:00:00Z"), null, false, null); + } + + private SpaceState withReserved(SpaceState source) { + return new SpaceState(source.spaceId(), source.zoneCode(), source.laneCode(), source.depthOrder(), + source.laneCapacity(), source.floorNo(), source.aisleNo(), source.groupCoding(), source.rowCode(), + source.role(), source.status(), source.outboundTaskActive(), source.inventoryProjectConflict(), + source.trayNo(), source.projectNo(), source.productId(), source.lotNo(), source.inboundAt(), + source.outboundAt(), true, source.rowVersion()); + } + + private SpaceState withRole(SpaceState source, SpaceRole role) { + return new SpaceState(source.spaceId(), source.zoneCode(), source.laneCode(), source.depthOrder(), + source.laneCapacity(), source.floorNo(), source.aisleNo(), source.groupCoding(), source.rowCode(), + role, source.status(), source.outboundTaskActive(), source.inventoryProjectConflict(), + source.trayNo(), source.projectNo(), source.productId(), source.lotNo(), source.inboundAt(), + source.outboundAt(), source.reserved(), source.rowVersion()); + } + + private SpaceState withStatus(SpaceState source, SpaceStatus status) { + return new SpaceState(source.spaceId(), source.zoneCode(), source.laneCode(), source.depthOrder(), + source.laneCapacity(), source.floorNo(), source.aisleNo(), source.groupCoding(), source.rowCode(), + source.role(), status, source.outboundTaskActive(), source.inventoryProjectConflict(), + null, source.projectNo(), source.productId(), source.lotNo(), source.inboundAt(), + source.outboundAt(), source.reserved(), source.rowVersion()); + } + + private SpaceState space(String lane, int depth, String zone, int floor, int aisle, String row, Slot slot) { + return new SpaceState(lane + "-" + slot.depth, zone, lane, slot.depth, depth, floor, aisle, + slot.depth, row, SpaceRole.STORAGE, slot.status, slot.outbound, false, + slot.status == SpaceStatus.OCCUPIED ? lane + "-T" + slot.depth : null, + slot.project, slot.product, slot.lot, Instant.parse("2026-07-01T00:00:00Z"), + null, false, null); + } + + private Slot occupied(int depth, String project) { + return new Slot(depth, SpaceStatus.OCCUPIED, project, "M", "B", false); + } + + private Slot empty(int depth) { + return new Slot(depth, SpaceStatus.EMPTY, null, null, null, false); + } + + private Slot outboundEmpty(int depth) { + return new Slot(depth, SpaceStatus.EMPTY, null, null, null, true); + } + + private record Slot(int depth, SpaceStatus status, String project, String product, String lot, + boolean outbound) { + } +} diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/integration/AlgorithmConfigurationTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/integration/AlgorithmConfigurationTest.java new file mode 100644 index 0000000..8580cf0 --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/integration/AlgorithmConfigurationTest.java @@ -0,0 +1,54 @@ +package com.ruoyi.algorithm.integration; + +import com.ruoyi.algorithm.repository.JdbcWarehouseRepository; +import org.junit.jupiter.api.Test; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.support.TransactionTemplate; + +import javax.sql.DataSource; +import java.lang.reflect.Field; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; + +class AlgorithmConfigurationTest { + + @Test + void repositoryUsesTheWmsTransactionManagerBoundToItsDataSource() throws Exception { + DataSource dataSource = mock(DataSource.class); + DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource); + + Object repository = new AlgorithmConfiguration().algorithmWarehouseRepository( + dataSource, new AlgorithmProperties(), transactionManager); + + Field field = JdbcWarehouseRepository.class.getDeclaredField("transactions"); + field.setAccessible(true); + TransactionTemplate transactions = (TransactionTemplate) field.get(repository); + assertThat(transactions.getTransactionManager()).isSameAs(transactionManager); + } + + @Test + void repositoryRejectsATransactionManagerBoundToAnotherDataSource() { + DataSource algorithmDataSource = mock(DataSource.class); + DataSource otherDataSource = mock(DataSource.class); + DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(otherDataSource); + + assertThatThrownBy(() -> new AlgorithmConfiguration().algorithmWarehouseRepository( + algorithmDataSource, new AlgorithmProperties(), transactionManager)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("same DataSource"); + } + + @Test + void tidyRuntimeDefaultsAreConservativeAndReplayIsDisabled() { + AlgorithmProperties properties = new AlgorithmProperties(); + + assertThat(properties.getTidyAutoScanMs()).isEqualTo(600_000L); + assertThat(properties.getTidyReconcileMs()).isEqualTo(5_000L); + assertThat(properties.getTidyClaimLeaseSeconds()).isEqualTo(60); + assertThat(properties.getTidyWcsSnapshotUrl()).contains("tidyVehicleSnapshot"); + assertThat(properties.getReplayRunId()).isBlank(); + assertThat(properties.getReplayDatabase()).isBlank(); + } +} diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/integration/SchedulingRoutingPolicyTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/integration/SchedulingRoutingPolicyTest.java new file mode 100644 index 0000000..508d903 --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/integration/SchedulingRoutingPolicyTest.java @@ -0,0 +1,46 @@ +package com.ruoyi.algorithm.integration; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class SchedulingRoutingPolicyTest { + + @Test + void legacySkipsAlgorithmAndUsesStoredProcedure() { + SchedulingRoutingPolicy policy = new SchedulingRoutingPolicy(SchedulingMode.LEGACY, false); + + assertThat(policy.runAlgorithm()).isFalse(); + assertThat(policy.runLegacy(SchedulingDecisionStatus.READY)).isTrue(); + assertThat(policy.algorithmOwnsDecision()).isFalse(); + } + + @Test + void shadowCalculatesAlgorithmButKeepsLegacyBusinessWrites() { + SchedulingRoutingPolicy policy = new SchedulingRoutingPolicy(SchedulingMode.SHADOW, false); + + assertThat(policy.runAlgorithm()).isTrue(); + assertThat(policy.runLegacy(SchedulingDecisionStatus.READY)).isTrue(); + assertThat(policy.runLegacy(SchedulingDecisionStatus.WAITING)).isTrue(); + assertThat(policy.algorithmOwnsDecision()).isFalse(); + } + + @Test + void activeNeverFallsBackForWaitingOrBusinessRejection() { + SchedulingRoutingPolicy policy = new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, true); + + assertThat(policy.runAlgorithm()).isTrue(); + assertThat(policy.runLegacy(SchedulingDecisionStatus.READY)).isFalse(); + assertThat(policy.runLegacy(SchedulingDecisionStatus.WAITING)).isFalse(); + assertThat(policy.runLegacy(SchedulingDecisionStatus.REJECTED)).isFalse(); + assertThat(policy.algorithmOwnsDecision()).isTrue(); + } + + @Test + void activeTechnicalFallbackRequiresExplicitOptIn() { + assertThat(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false) + .runLegacy(SchedulingDecisionStatus.TECHNICAL_ERROR)).isFalse(); + assertThat(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, true) + .runLegacy(SchedulingDecisionStatus.TECHNICAL_ERROR)).isTrue(); + } +} diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/outbound/OutboundPlannerTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/outbound/OutboundPlannerTest.java new file mode 100644 index 0000000..44f38da --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/outbound/OutboundPlannerTest.java @@ -0,0 +1,266 @@ +package com.ruoyi.algorithm.outbound; + +import com.ruoyi.algorithm.model.SpaceRole; +import com.ruoyi.algorithm.model.SpaceState; +import com.ruoyi.algorithm.model.SpaceStatus; +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class OutboundPlannerTest { + + private final OutboundPlanner planner = new OutboundPlanner(); + + @Test + void projectIsRequiredWithoutTrayProductIsOptionalAndWholeTrayDefaultsTrue() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("M1", 1, 1, stock(1, "T-M1", "P", "M1", "2026-07-01T00:00:00Z"))); + spaces.addAll(lane("M2", 1, 1, stock(1, "T-M2", "P", "M2", "2026-07-02T00:00:00Z"))); + + OutboundPlan anyProduct = plan(request(null, "P", null, "OFF", null, null), spaces); + OutboundPlan filtered = plan(request(null, "P", "M2", "OFF", null, null), spaces); + OutboundPlan missingProject = plan(request(null, null, "M1", "OFF", null, null), spaces); + + assertThat(anyProduct.assignment().orElseThrow().trayNo()).isEqualTo("T-M1"); + assertThat(anyProduct.assignment().orElseThrow().wholeTray()).isTrue(); + assertThat(filtered.assignment().orElseThrow().trayNo()).isEqualTo("T-M2"); + assertThat(missingProject.error().orElseThrow().code()).isEqualTo(OutboundErrorCode.OUTBOUND_SCOPE_REQUIRED); + } + + @Test + void specifiedTrayIsNeverReplacedAndReportsItsRealFifoRankAndWarning() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("OLD", 1, 1, stock(1, "T-OLD", "P", "M", "2026-07-01T00:00:00Z"))); + spaces.addAll(lane("NEW", 1, 1, stock(1, "T-NEW", "P", "M", "2026-07-02T00:00:00Z"))); + + OutboundPlan result = plan(request("T-NEW", null, null, "STRICT", 0, true), spaces); + + assertThat(result.assignment().orElseThrow().trayNo()).isEqualTo("T-NEW"); + assertThat(result.assignment().orElseThrow().fifo().fifoRank()).isEqualTo(2); + assertThat(result.assignment().orElseThrow().fifo().fifoViolation()).isTrue(); + assertThat(result.assignment().orElseThrow().fifo().warning().orElseThrow().code()) + .isEqualTo("FIFO_OVERRIDDEN_BY_TRAY"); + } + + @Test + void fifoOffUsesActualBlockersThenCapacityModeLaneReleaseFloorAndSpaceId() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("DEEP", 5, 1, + stock(1, "T-DEEP", "P", "M", "2026-07-01T00:00:00Z"), + stock(2, "BLOCK", "X", "X", "2026-07-01T00:00:00Z"), empty(3), empty(4), empty(5))); + spaces.addAll(lane("A-SOLE", 1, 3, stock(1, "T-SOLE", "P", "M", "2026-07-03T00:00:00Z"))); + spaces.addAll(lane("B-NOT-SOLE", 2, 1, + stock(1, "OTHER", "X", "X", "2026-07-02T00:00:00Z"), + stock(2, "T-NEAR", "P", "M", "2026-07-02T00:00:00Z"))); + + OutboundPlan balanced = planner.plan(request(null, "P", "M", "OFF", null, true), + context(spaces, OutboundCapacityMode.BALANCED, Map.of())); + OutboundPlan warning = planner.plan(request(null, "P", "M", "OFF", null, true), + context(spaces, OutboundCapacityMode.WARNING, Map.of())); + + assertThat(balanced.assignment().orElseThrow().trayNo()).isEqualTo("T-NEAR"); + assertThat(warning.assignment().orElseThrow().trayNo()).isEqualTo("T-SOLE"); + assertThat(warning.assignment().orElseThrow().blockerSpaceIds()).isEmpty(); + assertThat(warning.assignment().orElseThrow().laneReleasing()).isTrue(); + } + + @Test + void strictFifoChoosesTheGlobalOldestEvenWhenItIsDeep() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("DEEP", 2, 2, + stock(1, "T-OLD", "P", "M", "2026-07-01T00:00:00Z"), + stock(2, "BLOCK", "X", "X", "2026-07-01T01:00:00Z"))); + spaces.addAll(lane("DIRECT", 1, 1, + stock(1, "T-NEW", "P", "M", "2026-07-03T00:00:00Z"))); + spaces.addAll(buffers(2, 1)); + + OutboundAssignment assignment = plan(request(null, "P", "M", "STRICT", 0, true), spaces) + .assignment().orElseThrow(); + + assertThat(assignment.trayNo()).isEqualTo("T-OLD"); + assertThat(assignment.blockerSpaceIds()).containsExactly("DEEP-2"); + assertThat(assignment.fifo().fifoRank()).isEqualTo(1); + } + + @Test + void flexibleFifoOptimizesOnlyInsideTheOldestToleranceWindow() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("OLD", 2, 1, + stock(1, "T-OLD", "P", "M", "2026-07-01T00:00:00Z"), + stock(2, "BLOCK", "X", "X", "2026-07-01T01:00:00Z"))); + spaces.addAll(lane("WINDOW", 1, 2, + stock(1, "T-WINDOW", "P", "M", "2026-07-01T00:30:00Z"))); + spaces.addAll(lane("LATE", 1, 1, + stock(1, "T-LATE", "P", "M", "2026-07-02T00:00:00Z"))); + spaces.addAll(buffers(1, 1)); + + OutboundAssignment assignment = plan(request(null, "P", "M", "FLEXIBLE", 60, true), spaces) + .assignment().orElseThrow(); + + assertThat(assignment.trayNo()).isEqualTo("T-WINDOW"); + assertThat(assignment.fifo().fifoDeviationMinutes()).isEqualTo(30); + } + + @Test + void missingAndInvalidFifoTimesReturnStructuredErrors() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("VALID", 1, 1, stock(1, "T-VALID", "P", "M", "2026-07-01T00:00:00Z"))); + spaces.addAll(lane("BAD", 1, 1, stock(1, "T-BAD", "P", "M", null))); + + OutboundPlan missing = planner.plan(request(null, "P", "M", "STRICT", 0, true), + context(spaces, OutboundCapacityMode.BALANCED, Map.of())); + OutboundPlan invalid = planner.plan(request(null, "P", "M", "STRICT", 0, true), + context(spaces, OutboundCapacityMode.BALANCED, Map.of("BAD-1", "not-a-time"))); + + assertThat(missing.error().orElseThrow().code()).isEqualTo(OutboundErrorCode.FIFO_DATA_MISSING); + assertThat(missing.error().orElseThrow().details()).containsEntry("spaceIds", List.of("BAD-1")); + assertThat(invalid.error().orElseThrow().code()).isEqualTo(OutboundErrorCode.FIFO_INVALID_TIME); + assertThat(invalid.error().orElseThrow().details()).containsEntry("spaceId", "BAD-1"); + } + + @Test + void insufficientSameFloorRelocationBuffersAlwaysWaitAndCountNoCompletedTasks() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("DEEP", 3, 4, + stock(1, "TARGET", "P", "M", "2026-07-01T00:00:00Z"), + stock(2, "B2", "X", "X", "2026-07-01T00:00:00Z"), + stock(3, "B3", "X", "X", "2026-07-01T00:00:00Z"))); + spaces.addAll(buffers(4, 1)); + + OutboundPlan plan = plan(request("TARGET", null, null, "OFF", null, true), spaces); + + assertThat(plan.status()).isEqualTo(OutboundPlanStatus.WAITING); + assertThat(plan.waiting().orElseThrow().code()).isEqualTo(OutboundWaitingCode.WAITING_RELOCATION_BUFFER); + assertThat(plan.waiting().orElseThrow().required()).isEqualTo(2); + assertThat(plan.waiting().orElseThrow().available()).isEqualTo(1); + assertThat(plan.waiting().orElseThrow().reason()).contains("same-floor relocation buffer"); + assertThat(plan.waiting().orElseThrow().retryable()).isTrue(); + assertThat(plan.taskCountEstimate()).isEqualTo(TaskCountEstimate.zero()); + assertThat(plan.error()).isEmpty(); + } + + @Test + void anActiveSameFloorDeepWorkflowSerializesTheNextOneEvenWhenBuffersRemain() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("DEEP", 2, 4, + stock(1, "TARGET", "P", "M", "2026-07-01T00:00:00Z"), + stock(2, "BLOCK", "X", "X", "2026-07-01T00:00:00Z"))); + spaces.addAll(buffers(4, 4)); + + OutboundPlan plan = planner.plan(request("TARGET", null, null, "OFF", null, true), + new OutboundContext(spaces, rawTimes(spaces), OutboundCapacityMode.BALANCED, Set.of(4))); + + assertThat(plan.status()).isEqualTo(OutboundPlanStatus.WAITING); + assertThat(plan.waiting().orElseThrow().code()).isEqualTo(OutboundWaitingCode.WAITING_RELOCATION_BUFFER); + assertThat(plan.waiting().orElseThrow().reason()).contains("active same-floor deep workflow"); + assertThat(plan.waiting().orElseThrow().required()).isEqualTo(1); + assertThat(plan.waiting().orElseThrow().available()).isEqualTo(4); + assertThat(plan.taskCountEstimate()).isEqualTo(TaskCountEstimate.zero()); + } + + @Test + void deepOutboundBuildsSequentialMoveOutOutboundRestoreWorkflowAndWholeWorkflowLocks() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("DEEP", 3, 2, + stock(1, "TARGET", "P", "M", "2026-07-01T00:00:00Z"), + stock(2, "B2", "X", "X", "2026-07-01T00:00:00Z"), + stock(3, "B3", "X", "X", "2026-07-01T00:00:00Z"))); + spaces.addAll(buffers(2, 2)); + + OutboundPlan plan = plan(request("TARGET", null, null, "OFF", null, true), spaces); + OutboundWorkflow workflow = plan.assignment().orElseThrow().workflow().orElseThrow(); + + assertThat(plan.status()).isEqualTo(OutboundPlanStatus.READY); + assertThat(plan.assignment().orElseThrow().blockerSpaceIds()).containsExactly("DEEP-3", "DEEP-2"); + assertThat(workflow.steps()).extracting(OutboundWorkflowStep::phase) + .containsExactly(OutboundWorkflowPhase.MOVE_OUT, OutboundWorkflowPhase.MOVE_OUT, + OutboundWorkflowPhase.OUTBOUND, OutboundWorkflowPhase.RESTORE, + OutboundWorkflowPhase.RESTORE); + assertThat(workflow.steps()).extracting(OutboundWorkflowStep::dependsOnAssignmentId) + .containsExactly(null, "REQ-MOVE-OUT-01", "REQ-MOVE-OUT-02", "REQ-OUTBOUND-01", "REQ-RESTORE-01"); + assertThat(workflow.steps().get(0).sourceSpaceId()).isEqualTo("DEEP-3"); + assertThat(workflow.steps().get(3).targetSpaceId()).isEqualTo("DEEP-1"); + assertThat(workflow.steps().get(4).targetSpaceId()).isEqualTo("DEEP-2"); + assertThat(workflow.lockedLaneSpaceIds()).containsExactly("DEEP-1", "DEEP-2", "DEEP-3"); + assertThat(workflow.lockedBufferSpaceIds()).containsExactly("BUFFER-2-1", "BUFFER-2-2"); + assertThat(workflow.lockReleaseRule()).isEqualTo("RELEASE_AFTER_FINAL_RESTORE"); + assertThat(plan.taskCountEstimate()).isEqualTo(new TaskCountEstimate(0, 1, 4, 1)); + } + + @Test + void stockNotFoundIsDifferentFromFifoErrorsAndWaiting() { + OutboundPlan plan = plan(request("MISSING", null, null, "STRICT", 0, true), List.of()); + + assertThat(plan.status()).isEqualTo(OutboundPlanStatus.ERROR); + assertThat(plan.error().orElseThrow().code()).isEqualTo(OutboundErrorCode.STOCK_NOT_FOUND); + assertThat(plan.waiting()).isEmpty(); + } + + private OutboundPlan plan(OutboundRequest request, List spaces) { + return planner.plan(request, context(spaces, OutboundCapacityMode.BALANCED, Map.of())); + } + + private OutboundContext context(List spaces, OutboundCapacityMode mode, + Map rawTimeOverrides) { + Map raw = rawTimes(spaces); + raw.putAll(rawTimeOverrides); + return new OutboundContext(spaces, raw, mode); + } + + private Map rawTimes(List spaces) { + Map raw = new HashMap<>(); + for (SpaceState space : spaces) { + if (space.inboundAt() != null) raw.put(space.spaceId(), space.inboundAt().toString()); + } + return raw; + } + + private OutboundRequest request(String tray, String project, String product, String fifoMode, + Integer tolerance, Boolean wholeTray) { + return new OutboundRequest("REQ", tray, project, product, fifoMode, tolerance, 1, wholeTray); + } + + private List buffers(int floor, int count) { + List buffers = new ArrayList<>(); + for (int i = 1; i <= count; i++) { + buffers.add(space("BUFFER-" + floor, 1, floor, i, SpaceRole.RELOCATION_BUFFER, + SpaceStatus.EMPTY, null, null, null, null)); + } + return buffers; + } + + private List lane(String code, int capacity, int floor, Slot... slots) { + List spaces = new ArrayList<>(); + for (Slot slot : slots) { + spaces.add(space(code, capacity, floor, slot.depth(), SpaceRole.STORAGE, slot.status(), + slot.tray(), slot.project(), slot.product(), slot.inboundTime())); + } + return spaces; + } + + private SpaceState space(String lane, int capacity, int floor, int depth, SpaceRole role, + SpaceStatus status, String tray, String project, String product, String inboundTime) { + return new SpaceState(lane + "-" + depth, "MAIN", lane, depth, capacity, floor, 6, depth, + "1", role, status, false, false, tray, project, product, "LOT", + inboundTime == null ? null : Instant.parse(inboundTime), null, false, "rv"); + } + + private Slot stock(int depth, String tray, String project, String product, String inboundTime) { + return new Slot(depth, SpaceStatus.OCCUPIED, tray, project, product, inboundTime); + } + + private Slot empty(int depth) { + return new Slot(depth, SpaceStatus.EMPTY, null, null, null, null); + } + + private record Slot(int depth, SpaceStatus status, String tray, String project, String product, + String inboundTime) { + } +} diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepositorySqlServerTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepositorySqlServerTest.java new file mode 100644 index 0000000..ae761e5 --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepositorySqlServerTest.java @@ -0,0 +1,32 @@ +package com.ruoyi.algorithm.repository; + +import org.junit.jupiter.api.Test; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class JdbcWarehouseRepositorySqlServerTest { + @Test + void incrementalRefreshCallsOnlyDirtyLaneProcedure() throws Exception { + DataSource dataSource = mock(DataSource.class); + Connection connection = mock(Connection.class); + PreparedStatement statement = mock(PreparedStatement.class); + when(dataSource.getConnection()).thenReturn(connection); + when(connection.prepareStatement(anyString())).thenReturn(statement); + when(statement.executeUpdate()).thenReturn(0); + JdbcWarehouseRepository repository = new JdbcWarehouseRepository( + dataSource, RepositoryDialect.sqlServer()); + + repository.refreshChangedLanes("W1"); + + verify(connection).prepareStatement("EXEC alg.usp_refresh_dirty_lanes @warehouse_id=?"); + verify(statement).setString(1, "W1"); + verify(statement).executeUpdate(); + } +} diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepositoryTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepositoryTest.java new file mode 100644 index 0000000..91a8572 --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepositoryTest.java @@ -0,0 +1,594 @@ +package com.ruoyi.algorithm.repository; + +import com.ruoyi.algorithm.inbound.InboundPolicy; +import com.ruoyi.algorithm.inbound.InboundPlanner; +import com.ruoyi.algorithm.inbound.InboundRequest; +import com.ruoyi.algorithm.inbound.BatchLaneMode; +import com.ruoyi.algorithm.outbound.OutboundPlan; +import com.ruoyi.algorithm.outbound.OutboundPlanStatus; +import com.ruoyi.algorithm.outbound.OutboundPlanner; +import com.ruoyi.algorithm.outbound.OutboundRequest; +import com.ruoyi.algorithm.outbound.OutboundWaitingCode; +import com.ruoyi.algorithm.tidy.TidyPlanner; +import com.ruoyi.algorithm.service.WarehouseApplicationService; +import org.h2.tools.RunScript; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.jdbc.datasource.DriverManagerDataSource; + +import javax.sql.DataSource; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.sql.Connection; +import java.sql.Statement; +import java.sql.Types; +import java.sql.Timestamp; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class JdbcWarehouseRepositoryTest { + private DataSource dataSource; + private JdbcWarehouseRepository repository; + + @BeforeEach + void setUp() throws Exception { + dataSource = new DriverManagerDataSource( + "jdbc:h2:mem:repo_" + UUID.randomUUID() + ";MODE=MSSQLServer;DB_CLOSE_DELAY=-1", "sa", ""); + try (Connection connection = dataSource.getConnection()) { + RunScript.execute(connection, new InputStreamReader( + getClass().getClassLoader().getResourceAsStream("db/h2/schema.sql"), StandardCharsets.UTF_8)); + RunScript.execute(connection, new InputStreamReader( + getClass().getClassLoader().getResourceAsStream("db/h2/data.sql"), StandardCharsets.UTF_8)); + } + repository = new JdbcWarehouseRepository(dataSource, RepositoryDialect.h2()); + } + + @Test + void pagesCandidateLanesByStableKeyWithoutDuplicatesOrSkippedCodes() throws Exception { + execute("INSERT INTO ALG_LANE_STATE VALUES ('W1','A-LANE',1,0,1,FALSE,FALSE,'',11,CURRENT_TIMESTAMP)"); + execute("INSERT INTO ALG_LANE_STATE VALUES ('W1','B-LANE',1,0,1,FALSE,FALSE,'',12,CURRENT_TIMESTAMP)"); + execute("INSERT INTO ALG_LANE_STATE VALUES ('W1','C-LANE',1,0,1,FALSE,FALSE,'',13,CURRENT_TIMESTAMP)"); + execute("INSERT INTO ALG_LANE_STATE VALUES ('W1','SKIP-PENDING',1,0,1,TRUE,FALSE,'',14,CURRENT_TIMESTAMP)"); + execute("INSERT INTO ALG_LANE_STATE VALUES ('W1','SKIP-GAP',1,0,1,FALSE,TRUE,'',15,CURRENT_TIMESTAMP)"); + + LanePage first = repository.pageCandidateLanes("W1", null, 2); + LanePage second = repository.pageCandidateLanes("W1", first.nextLaneCode(), 2); + + assertThat(first.lanes()).extracting(LaneCandidate::laneCode).containsExactly("A-LANE", "B-LANE"); + assertThat(second.lanes()).extracting(LaneCandidate::laneCode).containsExactly("C-LANE", "DENSE-1"); + assertThat(first.lanes()).allMatch(lane -> lane.version().kind() == VersionToken.Kind.NUMERIC); + } + + @Test + void mapsCompleteDiagnosticSnapshotsWithoutDuplicatingSpaces() throws Exception { + execute("INSERT INTO BAS_STOCK VALUES ('S-OUT-2','OUT-INNER','TRAY-OUT','P-OUT','SKU-OUT','LOT-OUT','2026-01-01 09:00:00',5,0)"); + + List lanes = repository.loadLaneSnapshots("W1", + List.of("OUT-1", "CONFLICT-1", "BUFFER-1", "GAP-1")); + + assertThat(lanes).flatExtracting(LaneSnapshot::spaces).extracting(SpaceSnapshot::spaceId) + .containsExactly("BUFFER-1", "CONFLICT-1", "GAP-INNER", "GAP-OUTER", "OUT-INNER", "OUT-OUTER"); + SpaceSnapshot outbound = space(lanes, "OUT-INNER"); + assertThat(outbound.inventory()).hasSize(2); + assertThat(outbound.state().trayNo()).isEqualTo("TRAY-OUT"); + assertThat(outbound.state().outboundTaskActive()).isTrue(); + assertThat(space(lanes, "BUFFER-1").state().role()).isEqualTo(com.ruoyi.algorithm.model.SpaceRole.RELOCATION_BUFFER); + assertThat(space(lanes, "CONFLICT-1").conflicts()).contains(SpaceConflict.TRAY, SpaceConflict.PROJECT); + assertThat(space(lanes, "CONFLICT-1").state().status()).isEqualTo(com.ruoyi.algorithm.model.SpaceStatus.DISABLED); + assertThat(space(lanes, "GAP-INNER").state().status()).isEqualTo(com.ruoyi.algorithm.model.SpaceStatus.DISABLED); + assertThat(space(lanes, "BUFFER-1").state().aisleNo()).isEqualTo(1); + assertThat(space(lanes, "BUFFER-1").state().rowCode()).isEqualTo("3"); + assertThat(space(lanes, "BUFFER-1").state().zoneCode()).isEqualTo("CACHE"); + assertThat(space(lanes, "OUT-INNER").state().zoneCode()).isEqualTo("FLEX"); + } + + @Test + void statusFourPhysicalOuterPalletIsPreservedAndMakesDeepOutboundWait() throws Exception { + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('ALLOC-TARGET','W1','RA','A','Target',7,21,2,'2',''," + + "'TRAY-TARGET','ALLOC-LANE','1')"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('ALLOC-OUTER','W1','RA','A','Allocated outer',7,22,2,'4',''," + + "'TRAY-ALLOC','ALLOC-LANE','2')"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('ALLOC-BUFFER','W1','RB','E','Floor 2 buffer',8,23,2,'1',''," + + "NULL,'ALLOC-BUFFER','1')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-ALLOC-TARGET','ALLOC-TARGET','TRAY-TARGET','P-TARGET','SKU','LOT'," + + "'2026-01-01 08:00:00',1,0)"); + execute("INSERT INTO BAS_STOCK VALUES ('S-ALLOC-OUTER','ALLOC-OUTER','TRAY-ALLOC','P-BLOCK','SKU','LOT'," + + "'2026-01-01 09:00:00',1,0)"); + execute("INSERT INTO ALG_SPACE_ROLE (SPACE_ID,ROLE) VALUES ('ALLOC-BUFFER','RELOCATION_BUFFER')"); + rebuildTopology("W1"); + + SpaceSnapshot allocated = space(repository.loadLaneSnapshots("W1", List.of("ALLOC-LANE")), "ALLOC-OUTER"); + OutboundPlan result = new WarehouseApplicationService(repository, new InboundPlanner(), + new OutboundPlanner(), new TidyPlanner(), 100).planOutbound("W1", + new OutboundRequest("ALLOC-REQ", "TRAY-TARGET", null, null, "OFF", 0, 1, true)); + + assertThat(allocated.state().occupied()).isTrue(); + assertThat(allocated.state().trayNo()).isEqualTo("TRAY-ALLOC"); + assertThat(allocated.state().projectNo()).isEqualTo("P-BLOCK"); + assertThat(result.status()).isEqualTo(OutboundPlanStatus.WAITING); + assertThat(result.waiting().orElseThrow().code()).isEqualTo(OutboundWaitingCode.WAITING_CHANNEL); + assertThat(result.waiting().orElseThrow().retryable()).isTrue(); + assertThat(result.waiting().orElseThrow().details()) + .containsEntry("blockingSpaceIds", List.of("ALLOC-OUTER")) + .containsEntry("blockingTrayNos", List.of("TRAY-ALLOC")); + } + + @Test + void statusFourStockWithoutAnyTrayCodeStillBlocksDeepOutbound() throws Exception { + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('NO-TRAY-TARGET','W1','RA','A','Target',7,27,2,'2',''," + + "'TRAY-NO-TRAY-TARGET','NO-TRAY-LANE','1')"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('NO-TRAY-OUTER','W1','RA','A','Allocated outer',7,28,2,'4',''," + + "NULL,'NO-TRAY-LANE','2')"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('NO-TRAY-BUFFER','W1','RB','E','Floor 2 buffer',8,29,2,'1',''," + + "NULL,'NO-TRAY-BUFFER','1')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-NO-TRAY-TARGET','NO-TRAY-TARGET','TRAY-NO-TRAY-TARGET'," + + "'P-TARGET','SKU','LOT','2026-01-01 08:00:00',1,0)"); + execute("INSERT INTO BAS_STOCK VALUES ('S-NO-TRAY-OUTER','NO-TRAY-OUTER',NULL," + + "'P-BLOCK','SKU','LOT','2026-01-01 09:00:00',1,0)"); + execute("INSERT INTO ALG_SPACE_ROLE (SPACE_ID,ROLE) VALUES ('NO-TRAY-BUFFER','RELOCATION_BUFFER')"); + rebuildTopology("W1"); + + SpaceSnapshot outer = space(repository.loadLaneSnapshots("W1", List.of("NO-TRAY-LANE")), + "NO-TRAY-OUTER"); + OutboundPlan result = new WarehouseApplicationService(repository, new InboundPlanner(), + new OutboundPlanner(), new TidyPlanner(), 100).planOutbound("W1", + new OutboundRequest("NO-TRAY-REQ", "TRAY-NO-TRAY-TARGET", null, null, + "OFF", 0, 1, true)); + + assertThat(outer.state().trayNo()).isNull(); + assertThat(outer.state().occupied()).isTrue(); + assertThat(result.status()).isEqualTo(OutboundPlanStatus.WAITING); + assertThat(result.waiting().orElseThrow().code()).isEqualTo(OutboundWaitingCode.WAITING_CHANNEL); + assertThat(result.waiting().orElseThrow().details()) + .containsEntry("blockingSpaceIds", List.of("NO-TRAY-OUTER")); + } + + @Test + void projectOnlyStatusFourStockWithoutTrayReturnsRetryableWaiting() throws Exception { + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('PROJECT-NO-TRAY','W1','RA','A','Allocated source',7,30,2,'4',''," + + "NULL,'PROJECT-NO-TRAY-LANE','1')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-PROJECT-NO-TRAY','PROJECT-NO-TRAY',NULL," + + "'P-NO-TRAY','SKU','LOT','2026-01-01 09:00:00',1,0)"); + rebuildTopology("W1"); + + OutboundPlan result = new WarehouseApplicationService(repository, new InboundPlanner(), + new OutboundPlanner(), new TidyPlanner(), 100).planOutbound("W1", + new OutboundRequest("PROJECT-NO-TRAY-REQ", null, "P-NO-TRAY", null, + "OFF", 0, 1, true)); + + assertThat(result.status()).isEqualTo(OutboundPlanStatus.WAITING); + assertThat(result.waiting().orElseThrow().code()).isEqualTo(OutboundWaitingCode.WAITING_CHANNEL); + assertThat(result.waiting().orElseThrow().retryable()).isTrue(); + assertThat(result.waiting().orElseThrow().details()) + .containsEntry("sourceSpaceId", "PROJECT-NO-TRAY") + .containsEntry("laneCode", "PROJECT-NO-TRAY-LANE") + .doesNotContainKey("trayNo"); + } + + @Test + void exactCargoSpaceTrayWithoutMatchingStockIsWarehouseScopedAndWaits() throws Exception { + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('CARGO-ONLY-W1','W1','RA','A','Allocated source',7,24,2,'4',''," + + "'TRAY-CARGO-ONLY','CARGO-ONLY-LANE','1')"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('CARGO-ONLY-W2','W2','RA','A','Other warehouse',7,24,2,'2',''," + + "'TRAY-CARGO-ONLY','CARGO-ONLY-LANE','1')"); + rebuildTopology("W1"); + rebuildTopology("W2"); + + List matches = repository.searchOutboundStock("W1", + OutboundStockSearch.exactTray("TRAY-CARGO-ONLY")); + OutboundPlan result = new WarehouseApplicationService(repository, new InboundPlanner(), + new OutboundPlanner(), new TidyPlanner(), 100).planOutbound("W1", + new OutboundRequest("CARGO-ONLY-REQ", "TRAY-CARGO-ONLY", null, null, + "OFF", 0, 1, true)); + + assertThat(matches).extracting(OutboundStockMatch::spaceId).containsExactly("CARGO-ONLY-W1"); + assertThat(result.status()).isEqualTo(OutboundPlanStatus.WAITING); + assertThat(result.waiting().orElseThrow().code()).isEqualTo(OutboundWaitingCode.WAITING_CHANNEL); + assertThat(result.waiting().orElseThrow().retryable()).isTrue(); + assertThat(result.waiting().orElseThrow().details()) + .containsEntry("sourceSpaceId", "CARGO-ONLY-W1") + .containsEntry("trayNo", "TRAY-CARGO-ONLY"); + } + + @Test + void exactTraySearchKeepsCargoAndInventoryLocationsAmbiguous() throws Exception { + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('DUP-CARGO','W1','RA','A','Cargo location',7,25,2,'4',''," + + "'TRAY-DUP','DUP-CARGO-LANE','1')"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('DUP-STOCK','W1','RA','A','Stock location',7,26,2,'2',''," + + "NULL,'DUP-STOCK-LANE','1')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-DUP','DUP-STOCK','TRAY-DUP','P-DUP','SKU','LOT'," + + "'2026-01-01 08:00:00',1,0)"); + rebuildTopology("W1"); + + List matches = repository.searchOutboundStock("W1", + OutboundStockSearch.exactTray("TRAY-DUP")); + OutboundPlan result = new WarehouseApplicationService(repository, new InboundPlanner(), + new OutboundPlanner(), new TidyPlanner(), 100).planOutbound("W1", + new OutboundRequest("DUP-REQ", "TRAY-DUP", null, null, "OFF", 0, 1, true)); + + assertThat(matches).extracting(OutboundStockMatch::spaceId) + .containsExactly("DUP-STOCK", "DUP-CARGO"); + assertThat(result.error().orElseThrow().code()).isEqualTo(com.ruoyi.algorithm.outbound.OutboundErrorCode.AMBIGUOUS_TRAY); + } + + @Test + void derivesStableJavascriptZonesFromTopologyInsteadOfAreaId() throws Exception { + for (int index = 1; index <= 134; index++) { + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('Z-" + index + "','WZ','R','AREA-X','Zone',1," + index + + ",1,'1','',NULL,'ZL-" + index + "','1')"); + } + for (int depth = 1; depth <= 5; depth++) { + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('MAIN-" + depth + + "','WZ','R','AREA-Y','Main',2," + depth + ",1,'1','',NULL,'MAIN-LANE','" + depth + "')"); + } + rebuildTopology("WZ"); + + List lanes = repository.loadLaneSnapshots("WZ", + List.of("ZL-134", "ZL-54", "ZL-1", "MAIN-LANE")); + + assertThat(space(lanes, "Z-134").state().zoneCode()).isEqualTo("CACHE"); + assertThat(space(lanes, "Z-54").state().zoneCode()).isEqualTo("RESERVE"); + assertThat(space(lanes, "Z-1").state().zoneCode()).isEqualTo("FLEX"); + assertThat(space(lanes, "MAIN-1").state().zoneCode()).isEqualTo("MAIN"); + } + + @Test + void searchesExactTrayOrProjectWithOptionalProduct() { + assertThat(repository.searchOutboundStock("W1", OutboundStockSearch.exactTray("TRAY-OUT"))) + .extracting(OutboundStockMatch::spaceId).containsExactly("OUT-INNER"); + assertThat(repository.searchOutboundStock("W1", OutboundStockSearch.project("P-OUT", null))) + .extracting(OutboundStockMatch::trayNo).containsExactly("TRAY-OUT"); + assertThat(repository.searchOutboundStock("W1", OutboundStockSearch.project("P-OUT", "NOPE"))).isEmpty(); + } + + @Test + void countsOnlySelectableProjectPalletsWithInventoryOrSpaceTrayFallback() throws Exception { + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('VIS-1','W1','RV','A','Visible',9,10,1,'2','','TRAY-V1','VIS-1','1')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-V1-A','VIS-1','TRAY-V1','P-VIS','SKU','L','2026-01-01 10:00:00',1,0)"); + execute("INSERT INTO BAS_STOCK VALUES ('S-V1-B','VIS-1','TRAY-V1','P-VIS','SKU','L','2026-01-01 10:01:00',1,0)"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('VIS-2','W1','RV','A','Fallback',9,11,1,'2','','TRAY-V2','VIS-2','1')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-V2','VIS-2',NULL,'P-VIS','SKU','L','2026-01-01 10:02:00',1,0)"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('VIS-LOCK','W1','RV','A','Locked',9,12,1,'2','1','TRAY-L','VIS-L','1')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-VL','VIS-LOCK','TRAY-L','P-VIS','SKU','L','2026-01-01 10:03:00',1,0)"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('VIS-INVALID','W1','RV','A','Invalid',9,13,1,'2','','TRAY-I','VIS-I','X')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-VI','VIS-INVALID','TRAY-I','P-VIS','SKU','L','2026-01-01 10:04:00',1,0)"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('VIS-EMPTY','W1','RV','A','Empty mismatch',9,14,1,'1','','TRAY-E','VIS-E','1')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-VE','VIS-EMPTY','TRAY-E','P-VIS','SKU','L','2026-01-01 10:05:00',1,0)"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('VIS-RES','W1','RV','A','Reserved',9,15,1,'2','','TRAY-R','VIS-R','1')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-VR','VIS-RES','TRAY-R','P-VIS','SKU','L','2026-01-01 10:06:00',1,0)"); + execute("INSERT INTO ALG_RESERVATION (RESERVATION_ID,WAREHOUSE_ID,LANE_CODE,SPACE_ID,PROJECT_NO,STATUS) VALUES ('" + + UUID.randomUUID() + "','W1','VIS-R','VIS-RES','P-VIS','ACTIVE')"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('VIS-PEND','W1','RV','A','Pending',9,16,1,'2','','TRAY-P','VIS-P','1')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-VP','VIS-PEND','TRAY-P','P-VIS','SKU','L','2026-01-01 10:07:00',1,0)"); + execute("INSERT INTO MYDO_JOB VALUES ('JOB-VP','TASK-VP','TRAY-P','VIS-PEND',NULL,'W1','3',21,'2026-01-01 11:00:00','')"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('VIS-GAP-1','W1','RV','A','Gap inner',9,17,1,'1','',NULL,'VIS-G','1')"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('VIS-GAP-2','W1','RV','A','Gap outer',9,18,1,'2','','TRAY-G','VIS-G','2')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-VG','VIS-GAP-2','TRAY-G','P-VIS','SKU','L','2026-01-01 10:08:00',1,0)"); + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('VIS-CONFLICT','W1','RV','A','Conflict',9,19,1,'2','','TRAY-C','VIS-C','1')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-VC1','VIS-CONFLICT','TRAY-C1','P-VIS','SKU','L','2026-01-01 10:09:00',1,0)"); + execute("INSERT INTO BAS_STOCK VALUES ('S-VC2','VIS-CONFLICT','TRAY-C2','P-VIS','SKU','L','2026-01-01 10:10:00',1,0)"); + rebuildTopology("W1"); + + assertThat(repository.countProjectPallets("W1", "P-VIS")).isEqualTo(2); + } + + @Test + void treatsMultipleProductAndLotDetailsAsOneVisibleProjectPallet() throws Exception { + execute("INSERT INTO BAS_CARGO_SPACE VALUES ('VIS-LOT','W1','RV','A','Detailed pallet',9,20,1,'2','','TRAY-LOT','VIS-LOT','1')"); + execute("INSERT INTO BAS_STOCK VALUES ('S-VLOT-1','VIS-LOT','TRAY-LOT','P-LOT','SKU-1','LOT-1','2026-01-01 10:00:00',1,0)"); + execute("INSERT INTO BAS_STOCK VALUES ('S-VLOT-2','VIS-LOT','TRAY-LOT','P-LOT','SKU-2','LOT-2','2026-01-01 10:01:00',1,0)"); + rebuildTopology("W1"); + + SpaceSnapshot snapshot = space(repository.loadLaneSnapshots("W1", List.of("VIS-LOT")), "VIS-LOT"); + assertThat(snapshot.conflicts()).isEmpty(); + assertThat(snapshot.state().trayNo()).isEqualTo("TRAY-LOT"); + assertThat(snapshot.state().projectNo()).isEqualTo("P-LOT"); + assertThat(snapshot.state().productId()).isNull(); + assertThat(snapshot.state().lotNo()).isNull(); + assertThat(repository.countProjectPallets("W1", "P-LOT")).isOne(); + assertThat(repository.searchOutboundStock("W1", OutboundStockSearch.project("P-LOT", "SKU-2"))) + .extracting(OutboundStockMatch::spaceId).containsExactly("VIS-LOT"); + assertThat(repository.searchOutboundStock("W1", OutboundStockSearch.project("P-LOT", "SKU-X"))).isEmpty(); + } + + @Test + void insertsAndReadsCompactDecisionLog() { + String decisionId = UUID.randomUUID().toString(); + DecisionLogEntry inserted = repository.insertDecision(new DecisionLogRecord( + decisionId, "W1", "INBOUND", VersionToken.numeric(7), "READY", "selected AVAILABLE-1")); + + assertThat(repository.findDecision(inserted.decisionId())).contains(inserted); + assertThat(inserted.reason()).doesNotContain("password"); + } + + @Test + void bindsDecisionVersionWithTheDialectColumnType() { + assertThat(JdbcWarehouseRepository.decisionVersionSqlType(RepositoryDialect.sqlServer())) + .isEqualTo(Types.BINARY); + assertThat(JdbcWarehouseRepository.decisionVersionSqlType(RepositoryDialect.h2())) + .isEqualTo(Types.BIGINT); + } + + @Test + void loadsSummaryPoliciesPendingJobsAndSameFloorBuffersWithoutDetailSnapshots() { + WarehouseSummary summary = repository.loadSummary("W1"); + + assertThat(summary.spaceCount()).isEqualTo(12); + assertThat(summary.conflictSpaceCount()).isEqualTo(1); + assertThat(repository.loadPolicy("W1")).isEqualTo(RepositoryPolicy.defaults()); + assertThat(repository.loadPendingOutboundJobs("W1")).extracting(PendingOutboundJob::jobId) + .containsExactly("JOB-OUT-1"); + assertThat(repository.loadRelocationBuffers("W1", java.util.Set.of(1))) + .extracting(SpaceSnapshot::spaceId).containsExactly("BUFFER-1"); + } + + @Test + void projectPolicyOnlyDeniesMixingWhenExplicitlyConfiguredFalse() throws Exception { + execute("INSERT INTO ALG_PROJECT_POLICY (PROJECT_NO,IS_ISOLATED,IS_COMMON,ALLOW_MIXED) " + + "VALUES ('P-DENIED',FALSE,FALSE,FALSE)"); + execute("INSERT INTO ALG_PROJECT_POLICY (PROJECT_NO,IS_ISOLATED,IS_COMMON,ALLOW_MIXED) " + + "VALUES ('P-ALLOWED',FALSE,FALSE,TRUE)"); + + InboundPolicy policy = repository.loadPolicy("W1").inboundPolicy(); + + assertThat(policy.allowsMixed("P-DENIED")).isFalse(); + assertThat(policy.allowsMixed("P-ALLOWED")).isTrue(); + assertThat(policy.allowsMixed("P-UNCONFIGURED")).isTrue(); + } + + @Test + void reservesWithOpaqueVersionAndReturnsStructuredConflictsAndRelease() { + VersionToken version = repository.pageCandidateLanes("W1", "C-LANE", 10).lanes().stream() + .filter(lane -> lane.laneCode().equals("DENSE-1")).findFirst().orElseThrow().version(); + String reservationId = UUID.randomUUID().toString(); + + ReservationResult reserved = repository.tryReserveInbound(new InboundReservation( + reservationId, "W1", "DENSE-1", "DENSE-1", "P-NEW", version)); + ReservationResult stale = repository.tryReserveInbound(new InboundReservation( + UUID.randomUUID().toString(), "W1", "DENSE-1", "DENSE-2", "P-NEW", version)); + ReservationResult nullVersion = repository.tryReserveInbound(new InboundReservation( + UUID.randomUUID().toString(), "W1", "DENSE-1", "DENSE-2", "P-NEW", null)); + VersionToken current = repository.loadLaneSnapshots("W1", List.of("DENSE-1")).get(0).version(); + ReservationResult duplicate = repository.tryReserveInbound(new InboundReservation( + UUID.randomUUID().toString(), "W1", "DENSE-1", "DENSE-1", "P-NEW", current)); + + assertThat(reserved.status()).isEqualTo(ReservationStatus.RESERVED); + assertThat(stale.reasonCode()).isEqualTo("LANE_VERSION_MISMATCH"); + assertThat(nullVersion.reasonCode()).isEqualTo("LANE_VERSION_MISMATCH"); + assertThat(duplicate.reasonCode()).isEqualTo("ACTIVE_RESERVATION_EXISTS"); + assertThat(repository.releaseReservation("W1", reservationId).status()).isEqualTo(ReservationStatus.RELEASED); + assertThat(repository.releaseReservation("W1", reservationId).status()).isEqualTo(ReservationStatus.NOT_FOUND); + } + + @Test + void synchronizationInvalidatesSameCountInventoryAndPolicyChangesAndLiveGuardRejectsStaleToken() throws Exception { + repository.synchronizeReadModel("W1"); + VersionToken inventoryBefore = repository.loadLaneSnapshots("W1", List.of("OUT-1")).get(0).version(); + + execute("UPDATE BAS_STOCK SET SPARE4='P-REPLACED' WHERE STOCK_ID='S-OUT-1'"); + repository.synchronizeReadModel("W1"); + VersionToken inventoryAfter = repository.loadLaneSnapshots("W1", List.of("OUT-1")).get(0).version(); + + execute("INSERT INTO ALG_PROJECT_POLICY (PROJECT_NO,IS_ISOLATED,IS_COMMON,ALLOW_MIXED) " + + "VALUES ('P-SEMANTIC',TRUE,FALSE,FALSE)"); + repository.synchronizeReadModel("W1"); + VersionToken policyAfter = repository.loadLaneSnapshots("W1", List.of("OUT-1")).get(0).version(); + + VersionToken stale = repository.loadLaneSnapshots("W1", List.of("DENSE-1")).get(0).version(); + execute("UPDATE ALG_PROJECT_POLICY SET IS_ISOLATED=FALSE,ALLOW_MIXED=TRUE WHERE PROJECT_NO='P-SEMANTIC'"); + ReservationResult conflict = repository.tryReserveInbound(new InboundReservation( + UUID.randomUUID().toString(), "W1", "DENSE-1", "DENSE-1", "P-NEW", stale)); + + assertThat(inventoryAfter).isNotEqualTo(inventoryBefore); + assertThat(policyAfter).isNotEqualTo(inventoryAfter); + assertThat(conflict.reasonCode()).isEqualTo("LANE_VERSION_MISMATCH"); + } + + @Test + void changedJobRefreshAdvancesOnlyItsResolvedSourceLane() throws Exception { + repository.synchronizeReadModel("W1"); + VersionToken denseBefore = repository.loadLaneSnapshots("W1", List.of("DENSE-1")).get(0).version(); + VersionToken outboundBefore = repository.loadLaneSnapshots("W1", List.of("OUT-1")).get(0).version(); + execute("INSERT INTO MYDO_JOB (JOB_ID,TASK_NO,TRAY_CODE,CARGO_SPACE_ID,TARGET_CARGO_SPACE_ID," + + "WAREHOUSE_ID,STATUS,IN_OR_OUT,CREATE_TIME,FINISH_TIME) VALUES " + + "('JOB-DENSE-OUT','TASK-DENSE-OUT',NULL,'DENSE-1',NULL,'W1','1',21," + + "'2026-07-21 08:00:00','')"); + + repository.refreshChangedLanes("W1"); + + VersionToken denseAfter = repository.loadLaneSnapshots("W1", List.of("DENSE-1")).get(0).version(); + VersionToken outboundAfter = repository.loadLaneSnapshots("W1", List.of("OUT-1")).get(0).version(); + assertThat(denseAfter).isNotEqualTo(denseBefore); + assertThat(outboundAfter).isEqualTo(outboundBefore); + } + + @Test + void incrementalRefreshDoesNotRewriteUnchangedLaneSnapshots() throws Exception { + repository.synchronizeReadModel("W1"); + execute("UPDATE ALG_INVENTORY_ITEM_SNAPSHOT SET SYNCHRONIZED_AT='2000-01-01 00:00:00' " + + "WHERE STOCK_ID='S-CONFLICT-1'"); + executeLiveOnly("UPDATE BAS_STOCK SET SPARE4='P-REFRESHED' WHERE STOCK_ID='S-OUT-1'"); + + repository.refreshChangedLanes("W1"); + + try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) { + var result = statement.executeQuery("SELECT SYNCHRONIZED_AT FROM ALG_INVENTORY_ITEM_SNAPSHOT " + + "WHERE STOCK_ID='S-CONFLICT-1'"); + result.next(); + assertThat(result.getTimestamp(1)).isEqualTo(Timestamp.valueOf("2000-01-01 00:00:00")); + } + assertThat(repository.searchOutboundStock("W1", OutboundStockSearch.project("P-REFRESHED", null))) + .extracting(OutboundStockMatch::stockId).containsExactly("S-OUT-1"); + } + + @Test + void incrementalRefreshRebuildsTopologyOnlyForStructuralCargoChanges() throws Exception { + repository.synchronizeReadModel("W1"); + executeLiveOnly("UPDATE BAS_CARGO_SPACE SET LOCKED='1' WHERE CARGO_SPACE_ID='AVAILABLE-1'"); + + repository.refreshChangedLanes("W1"); + + assertThat(space(repository.loadLaneSnapshots("W1", List.of("AVAILABLE-1")), "AVAILABLE-1") + .state().status()).isEqualTo(com.ruoyi.algorithm.model.SpaceStatus.DISABLED); + executeLiveOnly("INSERT INTO BAS_CARGO_SPACE (CARGO_SPACE_ID,WAREHOUSE_ID,ROADWAY_ID,CARGO_AREA_ID," + + "CARGO_SPACE_NAME,THE_PLATOON,THE_COLUMN,THE_FLOOR,STATUS,LOCKED,TRAY_CODE," + + "GROUP_CODING_NO,GROUP_CODING) VALUES " + + "('NEW-STRUCTURE-1','W1','R9','A','New structure',9,1,1,'1','',NULL," + + "'NEW-STRUCTURE','1')"); + + repository.refreshChangedLanes("W1"); + + assertThat(repository.loadLaneSnapshots("W1", List.of("NEW-STRUCTURE"))) + .singleElement().satisfies(lane -> assertThat(lane.spaces()) + .extracting(SpaceSnapshot::spaceId).containsExactly("NEW-STRUCTURE-1")); + } + + @Test + void planningRefreshesChangedLiveProjectBeforeSelectingAndReserving() throws Exception { + execute("UPDATE BAS_CARGO_SPACE SET STATUS='2',TRAY_CODE='TRAY-P-SNAPSHOT' " + + "WHERE CARGO_SPACE_ID='DENSE-1'"); + execute("INSERT INTO BAS_STOCK VALUES ('S-P-SNAPSHOT','DENSE-1','TRAY-P-SNAPSHOT'," + + "'P-SNAPSHOT','SKU-P','LOT-P','2026-01-01 08:00:00',1,0)"); + repository.synchronizeReadModel("W1"); + + VersionToken synchronizedVersion = repository.loadLaneSnapshots("W1", List.of("DENSE-1")) + .get(0).version(); + String synchronizedReservation = UUID.randomUUID().toString(); + assertThat(repository.tryReserveInbound(new InboundReservation(synchronizedReservation, "W1", + "DENSE-1", "DENSE-2", "P-SNAPSHOT", synchronizedVersion)).status()) + .isEqualTo(ReservationStatus.RESERVED); + assertThat(repository.releaseReservation("W1", synchronizedReservation).status()) + .isEqualTo(ReservationStatus.RELEASED); + + executeLiveOnly("UPDATE BAS_STOCK SET SPARE4='Q-LIVE' WHERE STOCK_ID='S-P-SNAPSHOT'"); + String rebuildTrigger = UUID.randomUUID().toString(); + execute("INSERT INTO ALG_RESERVATION (RESERVATION_ID,WAREHOUSE_ID,LANE_CODE,SPACE_ID,PROJECT_NO,STATUS) " + + "VALUES ('" + rebuildTrigger + "','W1','DENSE-1','DENSE-2','P-SNAPSHOT','ACTIVE')"); + assertThat(repository.releaseReservation("W1", rebuildTrigger).status()) + .isEqualTo(ReservationStatus.RELEASED); + + WarehouseApplicationService service = new WarehouseApplicationService(repository, new InboundPlanner(), + new OutboundPlanner(), new TidyPlanner(), 100); + var planned = service.planInbound("W1", new InboundRequest("STALE-SNAPSHOT-PLAN", "TRAY-IN", "P-SNAPSHOT", + "SKU-P", "LOT-P", 2, 1, null, Set.of(), BatchLaneMode.OPEN)); + var assignment = planned.plan().assignment().orElseThrow(); + + assertThat(assignment.laneCode()).isEqualTo("AVAILABLE-1"); + assertThat(planned.laneVersion()).isNotNull(); + ReservationResult reserved = repository.tryReserveInbound(new InboundReservation( + UUID.randomUUID().toString(), "W1", assignment.laneCode(), assignment.spaceId(), + "P-SNAPSHOT", planned.laneVersion())); + assertThat(reserved.status()).isEqualTo(ReservationStatus.RESERVED); + } + + @Test + void pendingOutboundConflictPrecedesGenericEligibilityAndIdsAreUuidForBothDialects() throws Exception { + execute("INSERT INTO ALG_LANE_STATE VALUES ('W1','OUT-1',2,1,0,TRUE,FALSE,'',21,CURRENT_TIMESTAMP)"); + String reservationId = UUID.randomUUID().toString(); + + ReservationResult result = repository.tryReserveInbound(new InboundReservation( + reservationId, "W1", "OUT-1", "OUT-OUTER", "P", VersionToken.numeric(21))); + + assertThat(result.reasonCode()).isEqualTo("PENDING_OUTBOUND"); + assertThatThrownBy(() -> repository.tryReserveInbound(new InboundReservation( + "not-a-uuid", "W1", "DENSE-1", "DENSE-1", "P", VersionToken.numeric(7)))) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void livePendingJobBlocksReservationWithoutLaneStateRebuild() throws Exception { + VersionToken version = repository.pageCandidateLanes("W1", null, 100).lanes().stream() + .filter(lane -> lane.laneCode().equals("DENSE-1")).findFirst().orElseThrow().version(); + execute("INSERT INTO MYDO_JOB VALUES ('JOB-LIVE','TASK-LIVE',NULL,'DENSE-1',NULL,'W1','3',21," + + "'2026-07-20 10:00:00','')"); + + ReservationResult result = repository.tryReserveInbound(new InboundReservation( + UUID.randomUUID().toString(), "W1", "DENSE-1", "DENSE-1", "P", version)); + + assertThat(result.reasonCode()).isEqualTo("PENDING_OUTBOUND"); + } + + @Test + void deepWorkflowLocksAreOwnedExclusiveAndExcludeTheCurrentRequest() { + assertThat(repository.acquireDeepWorkflowLock("REQ-1", "W1", 1)).isTrue(); + assertThat(repository.acquireDeepWorkflowLock("REQ-1", "W1", 1)).isTrue(); + assertThat(repository.acquireDeepWorkflowLock("REQ-2", "W1", 1)).isFalse(); + + assertThat(repository.loadActiveDeepWorkflowFloors("W1", "REQ-1")).isEmpty(); + assertThat(repository.loadActiveDeepWorkflowFloors("W1", "REQ-2")).containsExactly(1); + assertThat(repository.releaseDeepWorkflowLock("REQ-2", "W1", 1)).isFalse(); + assertThat(repository.releaseDeepWorkflowLock("REQ-1", "W1", 1)).isTrue(); + assertThat(repository.loadActiveDeepWorkflowFloors("W1", null)).isEmpty(); + } + + @Test + void ordinaryOutboundJobsDoNotCreateDeepWorkflowLocks() throws Exception { + execute("DELETE FROM MYDO_JOB"); + execute("INSERT INTO MYDO_JOB VALUES ('JOB-DEEP','TASK-DEEP',NULL,'DENSE-1',NULL,'W1','3',21," + + "'2026-07-20 10:00:00','')"); + + assertThat(repository.loadActiveDeepWorkflowFloors("W1", null)).isEmpty(); + } + + @Test + void dialectConstructionIsFixedAndRepositorySqlHasNoPlannerExpressions() throws Exception { + assertThat(RepositoryDialect.class.getDeclaredConstructors()).allMatch(constructor -> + java.lang.reflect.Modifier.isPrivate(constructor.getModifiers())); + String source = java.nio.file.Files.readString(java.nio.file.Path.of( + "src/main/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepository.java")); + assertThat(source).doesNotContain("capacityScore", "efficiencyScore", "ladderRung", "targetDepth", + "expectedProjectPallets", "ROW_NUMBER", "LANE_TOPOLOGY"); + } + + private SpaceSnapshot space(List lanes, String id) { + return lanes.stream().flatMap(lane -> lane.spaces().stream()) + .filter(space -> space.spaceId().equals(id)).findFirst().orElseThrow(); + } + + private void execute(String sql) throws Exception { + try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + if (java.util.regex.Pattern.compile("(?i)\\bBAS_STOCK\\b").matcher(sql).find()) { + statement.executeUpdate("DELETE FROM ALG_SPACE_INVENTORY_SUMMARY"); + statement.executeUpdate("DELETE FROM ALG_INVENTORY_ITEM_SNAPSHOT"); + statement.executeUpdate("INSERT INTO ALG_INVENTORY_ITEM_SNAPSHOT " + + "(WAREHOUSE_ID,STOCK_ID,SPACE_ID,TRAY_CODE,PROJECT_NO,PRODUCT_NO,LOT_NO," + + "INBOUND_TIME_RAW,INBOUND_AT,QUANTITY,OUT_QUANTITY) " + + "SELECT C.WAREHOUSE_ID,S.STOCK_ID,S.CARGO_SPACE_ID,S.TRAY_CODE,S.SPARE4,S.PRODUCT_ID," + + "S.LOT_NO,S.IN_DATE,ALG_TRY_TIMESTAMP(S.IN_DATE),S.QUANTITY,S.OUT_QUANTITY " + + "FROM BAS_STOCK S JOIN BAS_CARGO_SPACE C ON C.CARGO_SPACE_ID=S.CARGO_SPACE_ID"); + statement.executeUpdate("INSERT INTO ALG_SPACE_INVENTORY_SUMMARY " + + "(WAREHOUSE_ID,SPACE_ID,STOCK_DETAIL_COUNT,STOCK_TRAY_COUNT,STOCK_PROJECT_COUNT,STOCK_PRODUCT_COUNT) " + + "SELECT WAREHOUSE_ID,SPACE_ID,COUNT(*),COUNT(DISTINCT NULLIF(TRIM(TRAY_CODE),''))," + + "COUNT(DISTINCT NULLIF(TRIM(PROJECT_NO),'')),COUNT(DISTINCT NULLIF(TRIM(PRODUCT_NO),'')) " + + "FROM ALG_INVENTORY_ITEM_SNAPSHOT GROUP BY WAREHOUSE_ID,SPACE_ID"); + } + } + } + + private void executeLiveOnly(String sql) throws Exception { + try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + } + } + + private void rebuildTopology(String warehouseId) throws Exception { + execute("DELETE FROM ALG_SPACE_TOPOLOGY WHERE WAREHOUSE_ID = '" + warehouseId + "'"); + execute("INSERT INTO ALG_SPACE_TOPOLOGY (WAREHOUSE_ID,SPACE_ID,LANE_CODE,LANE_DEPTH,BASE_ZONE) " + + "WITH LANE_TOPOLOGY AS (SELECT WAREHOUSE_ID,GROUP_CODING_NO AS LANE_CODE,COUNT(*) AS LANE_DEPTH," + + "MAX(THE_COLUMN) AS COLUMN_NO,MIN(THE_PLATOON) AS ROW_NO,MIN(THE_FLOOR) AS FLOOR_NO," + + "MIN(CARGO_SPACE_ID) AS STABLE_ID FROM BAS_CARGO_SPACE WHERE WAREHOUSE_ID = '" + warehouseId + + "' GROUP BY WAREHOUSE_ID,GROUP_CODING_NO), RANKED_LANES AS (SELECT LANE_TOPOLOGY.*," + + "CASE WHEN LANE_DEPTH=1 THEN ROW_NUMBER() OVER (PARTITION BY WAREHOUSE_ID ORDER BY " + + "CASE WHEN LANE_DEPTH=1 THEN 0 ELSE 1 END,COLUMN_NO DESC,ROW_NO ASC,FLOOR_NO ASC,STABLE_ID ASC) END " + + "AS SINGLE_DEPTH_RANK FROM LANE_TOPOLOGY) SELECT C.WAREHOUSE_ID,C.CARGO_SPACE_ID,C.GROUP_CODING_NO," + + "R.LANE_DEPTH,CASE WHEN R.LANE_DEPTH=1 AND R.SINGLE_DEPTH_RANK<=80 THEN 'CACHE' " + + "WHEN R.LANE_DEPTH=1 AND R.SINGLE_DEPTH_RANK<=133 THEN 'RESERVE' WHEN R.LANE_DEPTH=5 THEN 'MAIN' " + + "ELSE 'FLEX' END FROM BAS_CARGO_SPACE C JOIN RANKED_LANES R ON R.WAREHOUSE_ID=C.WAREHOUSE_ID " + + "AND R.LANE_CODE=C.GROUP_CODING_NO WHERE C.WAREHOUSE_ID='" + warehouseId + "'"); + } +} diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepositoryWriteGuardTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepositoryWriteGuardTest.java new file mode 100644 index 0000000..3c4fa35 --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/JdbcWarehouseRepositoryWriteGuardTest.java @@ -0,0 +1,41 @@ +package com.ruoyi.algorithm.repository; + +import org.h2.tools.RunScript; +import org.junit.jupiter.api.Test; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DriverManagerDataSource; + +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +class JdbcWarehouseRepositoryWriteGuardTest { + @Test + void disabledWritesKeepPlanningAuditInMemoryAndRejectAllShadowMutations() throws Exception { + var dataSource = new DriverManagerDataSource( + "jdbc:h2:mem:guard_" + UUID.randomUUID() + ";MODE=MSSQLServer;DB_CLOSE_DELAY=-1", "sa", ""); + try (var connection = dataSource.getConnection()) { + RunScript.execute(connection, new InputStreamReader( + getClass().getClassLoader().getResourceAsStream("db/h2/schema.sql"), StandardCharsets.UTF_8)); + RunScript.execute(connection, new InputStreamReader( + getClass().getClassLoader().getResourceAsStream("db/h2/data.sql"), StandardCharsets.UTF_8)); + } + JdbcWarehouseRepository repository = new JdbcWarehouseRepository(dataSource, RepositoryDialect.h2(), false); + JdbcTemplate jdbc = new JdbcTemplate(dataSource); + int before = jdbc.queryForObject("SELECT COUNT(*) FROM ALG_DECISION_LOG", Integer.class); + + DecisionLogEntry entry = repository.insertDecision(new DecisionLogRecord(UUID.randomUUID().toString(), + "W1", "INBOUND", VersionToken.numeric(7), "READY", "read-only planning")); + + assertThat(entry.createdAt()).isBeforeOrEqualTo(Instant.now()); + assertThat(jdbc.queryForObject("SELECT COUNT(*) FROM ALG_DECISION_LOG", Integer.class)).isEqualTo(before); + assertThat(repository.tryReserveInbound(new InboundReservation(UUID.randomUUID().toString(), "W1", + "DENSE-1", "DENSE-1", "P", VersionToken.numeric(7))).reasonCode()).isEqualTo("WRITES_DISABLED"); + assertThat(repository.releaseReservation("W1", UUID.randomUUID().toString()).reasonCode()).isEqualTo("WRITES_DISABLED"); + assertThat(repository.acquireDeepWorkflowLock("O-1", "W1", 1)).isFalse(); + assertThat(repository.releaseDeepWorkflowLock("O-1", "W1", 1)).isFalse(); + } +} diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/SqlServerMigrationScriptTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/SqlServerMigrationScriptTest.java new file mode 100644 index 0000000..5289b76 --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/repository/SqlServerMigrationScriptTest.java @@ -0,0 +1,200 @@ +package com.ruoyi.algorithm.repository; + +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; + +class SqlServerMigrationScriptTest { + @Test + void installDefinesPersistentOutboundWorkflowSchema() throws IOException { + String install = resource("db/sqlserver/install.sql"); + + assertThat(install).contains( + "CREATE TABLE alg.outbound_workflow (", + "CREATE TABLE alg.outbound_workflow_step (", + "CREATE TABLE alg.outbound_workflow_space (", + "CK_alg_outbound_workflow_status", + "CK_alg_outbound_workflow_step_phase", + "CK_alg_outbound_workflow_step_status", + "UX_alg_outbound_workflow_active_request", + "UX_alg_outbound_workflow_step_wms_job", + "UX_alg_outbound_workflow_space_active"); + } + + @Test + void installDefinesDirtyLaneQueueRefreshAndAllMutationSources() throws IOException { + String install = resource("db/sqlserver/install.sql"); + + assertThat(install).contains( + "CREATE TABLE alg.dirty_lane_queue (", + "CREATE PROCEDURE alg.usp_mark_dirty_lane", + "CREATE PROCEDURE alg.usp_refresh_dirty_lanes", + "CREATE TRIGGER dbo.trg_alg_dirty_bas_stock", + "CREATE TRIGGER dbo.trg_alg_dirty_bas_cargo_space", + "CREATE TRIGGER dbo.trg_alg_dirty_mydo_job", + "CREATE TRIGGER alg.trg_alg_dirty_space_role", + "CREATE TRIGGER alg.trg_alg_dirty_project_policy", + "CREATE TRIGGER alg.trg_alg_dirty_warehouse_policy"); + } + + @Test + void installDefinesPersistentTidyRuntimeSchemaAndConstraints() throws IOException { + String install = resource("db/sqlserver/install.sql"); + + assertThat(install).contains( + "CREATE TABLE alg.tidy_mode (", + "CREATE TABLE alg.tidy_lane_queue (", + "CREATE TABLE alg.tidy_workflow (", + "CREATE TABLE alg.tidy_step (", + "CREATE TABLE alg.tidy_space_lock (", + "CREATE TABLE alg.tidy_callback_event (", + "CK_alg_tidy_mode_effective_state", + "CK_alg_tidy_workflow_origin", + "CK_alg_tidy_workflow_status", + "CK_alg_tidy_space_lock_resource_type", + "UX_alg_tidy_space_lock_active", + "UX_alg_tidy_callback_event_key", + "UX_alg_tidy_workflow_active_auto", + "FK_alg_tidy_callback_event_step_workflow"); + } + + @Test + void installDefinesVersionedTidyLaneClaimAndSequenceSynchronization() throws IOException { + String install = resource("db/sqlserver/install.sql"); + + assertThat(install).contains( + "CREATE PROCEDURE alg.usp_claim_tidy_lane", + "@eligible_lane_codes varchar(max) = NULL", + "STRING_SPLIT(@eligible_lane_codes, '','')", + "CREATE PROCEDURE alg.usp_release_tidy_lane", + "CREATE PROCEDURE alg.usp_sync_replay_sequences", + "sp_getapplock", + "CK202607210002"); + } + + @Test + void installCompletesAlgorithmOwnedMoveJobsWithoutChangingTheLegacyProcedure() throws IOException { + String install = resource("db/sqlserver/install.sql"); + + assertThat(install).contains( + "CREATE PROCEDURE alg.usp_complete_move_job", + "in_or_out = ''28''", + "UPDATE dbo.bas_stock", + "INSERT INTO dbo.mydo_job_finish", + "DELETE FROM dbo.mydo_job"); + assertThat(install).doesNotContain("ALTER PROCEDURE dbo.proc_yk_complete"); + } + + @Test + void dirtyLaneRefreshPublishesRebuiltLanesToPersistentTidyQueue() throws IOException { + String install = resource("db/sqlserver/install.sql"); + String procedure = install.substring( + install.indexOf("CREATE PROCEDURE alg.usp_refresh_dirty_lanes"), + install.indexOf("IF OBJECT_ID(N'alg.usp_try_reserve_inbound'")); + + int rebuildLaneState = procedure.lastIndexOf("EXEC alg.usp_rebuild_lane_state"); + int publishTidyLane = procedure.indexOf("MERGE alg.tidy_lane_queue WITH (HOLDLOCK)"); + + assertThat(rebuildLaneState).isGreaterThanOrEqualTo(0); + assertThat(publishTidyLane).isGreaterThan(rebuildLaneState); + assertThat(procedure).contains( + "dirty_version = target.dirty_version + 1", + "queue_status = ''PENDING''"); + } + + @Test + void dirtyLaneRefreshReleasesQueueLocksBeforeReadingWarehouseTablesAndRequeuesFailures() + throws IOException { + String install = resource("db/sqlserver/install.sql"); + String procedure = install.substring( + install.indexOf("CREATE PROCEDURE alg.usp_refresh_dirty_lanes"), + install.indexOf("IF OBJECT_ID(N'alg.usp_try_reserve_inbound'")); + + int claimDelete = procedure.indexOf("DELETE queue"); + int claimCommit = procedure.indexOf("COMMIT TRANSACTION;", claimDelete); + int warehouseRead = procedure.indexOf("FROM dbo.bas_cargo_space", claimDelete); + + assertThat(claimDelete).isGreaterThanOrEqualTo(0); + assertThat(claimCommit).isBetween(claimDelete + 1, warehouseRead - 1); + assertThat(procedure).contains( + "BEGIN TRY", + "BEGIN CATCH", + "MERGE alg.dirty_lane_queue WITH (HOLDLOCK) AS target", + "THROW;"); + } + + @Test + void topologyRebuildExcludesUnconfiguredCargoSpacesAndDiagnosticsReportsThem() + throws IOException { + String install = resource("db/sqlserver/install.sql"); + String diagnostics = resource("db/sqlserver/diagnostics.sql"); + String procedure = install.substring( + install.indexOf("CREATE PROCEDURE alg.usp_rebuild_space_topology"), + install.indexOf("IF OBJECT_ID(N'alg.usp_sync_inventory_snapshot'")); + + assertThat(procedure).contains( + "NULLIF(LTRIM(RTRIM(group_coding_no)), '''') IS NOT NULL", + "TRY_CONVERT(int, group_coding) IS NOT NULL"); + assertThat(diagnostics).contains( + "excluded_from_algorithm_topology_count", + "group_coding_no IS NULL OR LTRIM(RTRIM(group_coding_no)) = ''", + "TRY_CONVERT(int, group_coding) IS NULL"); + } + + @Test + void diagnosticsAndUninstallCoverNewRuntimeObjects() throws IOException { + String diagnostics = resource("db/sqlserver/diagnostics.sql"); + String uninstall = resource("db/sqlserver/uninstall.sql"); + + assertThat(diagnostics).contains( + "FROM alg.dirty_lane_queue", + "FROM alg.outbound_workflow", + "FROM alg.tidy_mode", + "FROM alg.tidy_lane_queue", + "FROM alg.tidy_workflow", + "FROM alg.tidy_space_lock", + "PAUSED_RECOVERY"); + assertThat(uninstall).contains( + "DROP TRIGGER dbo.trg_alg_dirty_bas_stock", + "DROP PROCEDURE alg.usp_refresh_dirty_lanes", + "DROP PROCEDURE alg.usp_claim_tidy_lane", + "DROP PROCEDURE alg.usp_release_tidy_lane", + "DROP PROCEDURE alg.usp_sync_replay_sequences", + "DROP TABLE alg.tidy_callback_event", + "DROP TABLE alg.tidy_space_lock", + "DROP TABLE alg.tidy_step", + "DROP TABLE alg.tidy_workflow", + "DROP TABLE alg.tidy_lane_queue", + "DROP TABLE alg.tidy_mode", + "DROP TABLE alg.outbound_workflow_space", + "DROP TABLE alg.outbound_workflow_step", + "DROP TABLE alg.outbound_workflow", + "DROP TABLE alg.dirty_lane_queue"); + } + + @Test + void repeatedInstallDoesNotDiscardPendingDirtyLanes() throws IOException { + String install = resource("db/sqlserver/install.sql"); + String initialization = install.substring(install.lastIndexOf("IF NOT EXISTS (SELECT 1 FROM alg.space_topology)")); + + assertThat(initialization).contains( + "AND NOT EXISTS (SELECT 1 FROM alg.inventory_item_snapshot)", + "AND NOT EXISTS (SELECT 1 FROM alg.lane_state)"); + assertThat(initialization.indexOf("DELETE FROM alg.dirty_lane_queue")) + .isLessThan(initialization.indexOf("END;")); + assertThat(initialization.substring(initialization.indexOf("END;") + 4)) + .doesNotContain("DELETE FROM alg.dirty_lane_queue"); + } + + private String resource(String name) throws IOException { + try (var stream = getClass().getClassLoader().getResourceAsStream(name)) { + if (stream == null) { + throw new IOException("Missing test resource " + name); + } + return new String(stream.readAllBytes(), StandardCharsets.UTF_8); + } + } +} diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/service/WarehouseApplicationServiceTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/service/WarehouseApplicationServiceTest.java new file mode 100644 index 0000000..916c5ff --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/service/WarehouseApplicationServiceTest.java @@ -0,0 +1,568 @@ +package com.ruoyi.algorithm.service; + +import com.ruoyi.algorithm.inbound.BatchLaneMode; +import com.ruoyi.algorithm.inbound.InboundPlanner; +import com.ruoyi.algorithm.inbound.InboundRequest; +import com.ruoyi.algorithm.model.SpaceRole; +import com.ruoyi.algorithm.model.SpaceState; +import com.ruoyi.algorithm.model.SpaceStatus; +import com.ruoyi.algorithm.outbound.OutboundPlanStatus; +import com.ruoyi.algorithm.outbound.OutboundErrorCode; +import com.ruoyi.algorithm.outbound.OutboundPlanner; +import com.ruoyi.algorithm.outbound.OutboundRequest; +import com.ruoyi.algorithm.tidy.TidyPlanner; +import com.ruoyi.algorithm.repository.DecisionLogEntry; +import com.ruoyi.algorithm.repository.InboundReservation; +import com.ruoyi.algorithm.repository.LaneCandidate; +import com.ruoyi.algorithm.repository.LanePage; +import com.ruoyi.algorithm.repository.LaneSnapshot; +import com.ruoyi.algorithm.repository.OutboundStockMatch; +import com.ruoyi.algorithm.repository.RepositoryPolicy; +import com.ruoyi.algorithm.repository.ReservationResult; +import com.ruoyi.algorithm.repository.SpaceSnapshot; +import com.ruoyi.algorithm.repository.VersionToken; +import com.ruoyi.algorithm.repository.WarehouseRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class WarehouseApplicationServiceTest { + private WarehouseRepository repository; + private WarehouseApplicationService service; + + @BeforeEach + void setUp() { + repository = mock(WarehouseRepository.class); + service = new WarehouseApplicationService(repository, new InboundPlanner(), new OutboundPlanner(), + new TidyPlanner(), 100); + when(repository.loadPolicy("W1")).thenReturn(RepositoryPolicy.defaults()); + when(repository.loadSummary("W1")).thenReturn(new com.ruoyi.algorithm.repository.WarehouseSummary( + "W1", 0, 0, 0, 0, 0, 0, 0)); + when(repository.loadPendingOutboundJobs("W1")).thenReturn(List.of()); + when(repository.countProjectPallets(any(), any())).thenReturn(0); + when(repository.loadActiveDeepWorkflowFloors(eq("W1"), any())).thenReturn(Set.of()); + when(repository.insertDecision(any())).thenAnswer(invocation -> { + var value = invocation.getArgument(0, com.ruoyi.algorithm.repository.DecisionLogRecord.class); + return new DecisionLogEntry(value.decisionId(), value.warehouseId(), value.decisionType(), + value.inputVersion(), value.resultCode(), value.reason(), Instant.parse("2026-07-20T00:00:00Z")); + }); + } + + @Test + void repositoryExposesIncrementalLaneRefreshContract() { + assertThat(List.of(WarehouseRepository.class.getMethods()).stream() + .map(Method::getName)) + .contains("refreshChangedLanes"); + } + + @Test + void inboundRefreshesChangedLanesBeforeReadingPlanningState() { + when(repository.pageCandidateLanes("W1", null, 100)).thenReturn(new LanePage(List.of(), null)); + + service.planInbound("W1", inbound("I-REFRESH")); + + org.mockito.InOrder order = org.mockito.Mockito.inOrder(repository); + order.verify(repository).refreshChangedLanes("W1"); + order.verify(repository).loadPolicy("W1"); + } + + @Test + void outboundRefreshesChangedLanesBeforeReadingPlanningState() { + OutboundRequest request = new OutboundRequest("O-REFRESH", null, "P", null, + "OFF", null, 1, true); + when(repository.searchOutboundStock("W1", + com.ruoyi.algorithm.repository.OutboundStockSearch.project("P", null))).thenReturn(List.of()); + + service.planOutbound("W1", request); + + org.mockito.InOrder order = org.mockito.Mockito.inOrder(repository); + order.verify(repository).refreshChangedLanes("W1"); + order.verify(repository).loadPolicy("W1"); + } + + @Test + void inboundDelegatesToPlannerLogsReadyAndNeverReservesDuringPlanning() { + VersionToken version = VersionToken.numeric(7); + LaneSnapshot lane = lane("L1", version, empty("L1", 1, 2), empty("L1", 2, 2)); + when(repository.pageCandidateLanes("W1", null, 100)).thenReturn(new LanePage(List.of( + new LaneCandidate("W1", "L1", 2, 0, 2, false, false, version)), null)); + when(repository.loadLaneSnapshots("W1", List.of("L1"))).thenReturn(List.of(lane)); + when(repository.loadSummary("W1")).thenReturn(new com.ruoyi.algorithm.repository.WarehouseSummary( + "W1", 1, 2, 0, 2, 0, 0, 0)); + + InboundPlanningResult result = service.planInbound("W1", inbound("I-READY")); + + assertThat(result.plan().assignment()).isPresent(); + assertThat(result.laneVersion()).isEqualTo(version); + verify(repository, never()).tryReserveInbound(any()); + verify(repository).insertDecision(any()); + } + + @Test + void inboundRejectionRemainsARejection() { + when(repository.pageCandidateLanes("W1", null, 100)).thenReturn(new LanePage(List.of(), null)); + when(repository.loadSummary("W1")).thenReturn(new com.ruoyi.algorithm.repository.WarehouseSummary( + "W1", 0, 0, 0, 0, 0, 0, 0)); + + InboundPlanningResult result = service.planInbound("W1", inbound("I-REJECT")); + + assertThat(result.plan().rejection()).isPresent(); + assertThat(result.laneVersion()).isNull(); + } + + @Test + void inboundUsesBoundedProjectAggregateWhenExpectedSizeIsMissing() { + VersionToken v2 = VersionToken.numeric(2); + VersionToken v5 = VersionToken.numeric(5); + LaneSnapshot shallow = lane("L2", v2, empty("L2", 1, 2), empty("L2", 2, 2)); + LaneSnapshot deep = lane("L5", v5, empty("L5", 1, 5), empty("L5", 2, 5), empty("L5", 3, 5), + empty("L5", 4, 5), empty("L5", 5, 5)); + when(repository.countProjectPallets("W1", "P")).thenReturn(3); + when(repository.loadSummary("W1")).thenReturn(new com.ruoyi.algorithm.repository.WarehouseSummary( + "W1", 2, 7, 3, 7, 0, 0, 0)); + when(repository.pageCandidateLanes("W1", null, 100)).thenReturn(new LanePage(List.of( + new LaneCandidate("W1", "L2", 2, 0, 2, false, false, v2), + new LaneCandidate("W1", "L5", 5, 0, 5, false, false, v5)), null)); + when(repository.loadLaneSnapshots("W1", List.of("L2", "L5"))).thenReturn(List.of(shallow, deep)); + InboundRequest request = new InboundRequest("I-SCALE", "T", "P", "SKU", "L", null, + 1, null, Set.of(), BatchLaneMode.OPEN); + + assertThat(service.planInbound("W1", request).plan().assignment().orElseThrow().laneCode()).isEqualTo("L5"); + } + + @Test + void inboundRetainsOnlyBoundedPageWinnersAndAValidLaterPageCandidateWins() throws Exception { + VersionToken firstVersion = VersionToken.numeric(21); + VersionToken laterVersion = VersionToken.numeric(22); + LaneSnapshot first = lane("A-LANE", firstVersion, + emptyAtFloor("A-LANE", 1, 2, 8), emptyAtFloor("A-LANE", 2, 2, 8)); + LaneSnapshot later = lane("Z-LANE", laterVersion, + emptyAtFloor("Z-LANE", 1, 2, 1), emptyAtFloor("Z-LANE", 2, 2, 1)); + when(repository.pageCandidateLanes("W1", null, 100)).thenReturn(new LanePage(List.of( + new LaneCandidate("W1", "A-LANE", 2, 0, 2, false, false, firstVersion)), "A-LANE")); + when(repository.pageCandidateLanes("W1", "A-LANE", 100)).thenReturn(new LanePage(List.of( + new LaneCandidate("W1", "Z-LANE", 2, 0, 2, false, false, laterVersion)), null)); + when(repository.loadLaneSnapshots("W1", List.of("A-LANE"))).thenReturn(List.of(first)); + when(repository.loadLaneSnapshots("W1", List.of("Z-LANE"))).thenReturn(List.of(later)); + + InboundPlanningResult result = service.planInbound("W1", inbound("I-PAGED")); + + assertThat(result.plan().assignment().orElseThrow().laneCode()).isEqualTo("Z-LANE"); + assertThat(result.laneVersion()).isEqualTo(laterVersion); + verify(repository).loadLaneSnapshots("W1", List.of("A-LANE")); + verify(repository).loadLaneSnapshots("W1", List.of("Z-LANE")); + String source = Files.readString(Path.of( + "src/main/java/com/ruoyi/algorithm/service/WarehouseApplicationService.java")); + int start = source.indexOf("public InboundPlanningResult planInbound"); + int end = source.indexOf("public OutboundPlan planOutbound", start); + String inboundMethod = source.substring(start, end); + assertThat(inboundMethod).contains("startPaged"); + assertThat(inboundMethod).doesNotContain("spaces.addAll", "List spaces = new ArrayList"); + } + + @Test + void inboundRejectsOnlyAfterEveryCandidatePageWasEvaluated() { + VersionToken firstVersion = VersionToken.numeric(31); + VersionToken lastVersion = VersionToken.numeric(32); + LaneSnapshot first = lane("BAD-A", firstVersion, + state("BAD-A", 1, 1, SpaceStatus.DISABLED, null, null, null)); + LaneSnapshot last = lane("BAD-Z", lastVersion, + state("BAD-Z", 1, 1, SpaceStatus.DISABLED, null, null, null)); + when(repository.pageCandidateLanes("W1", null, 100)).thenReturn(new LanePage(List.of( + new LaneCandidate("W1", "BAD-A", 1, 0, 1, false, false, firstVersion)), "BAD-A")); + when(repository.pageCandidateLanes("W1", "BAD-A", 100)).thenReturn(new LanePage(List.of( + new LaneCandidate("W1", "BAD-Z", 1, 0, 1, false, false, lastVersion)), null)); + when(repository.loadLaneSnapshots("W1", List.of("BAD-A"))).thenReturn(List.of(first)); + when(repository.loadLaneSnapshots("W1", List.of("BAD-Z"))).thenReturn(List.of(last)); + + InboundPlanningResult result = service.planInbound("W1", inbound("I-EXHAUSTIVE")); + + assertThat(result.plan().rejection()).isPresent(); + assertThat(result.laneVersion()).isNull(); + verify(repository).pageCandidateLanes("W1", "BAD-A", 100); + verify(repository).loadLaneSnapshots("W1", List.of("BAD-Z")); + } + + @Test + void resolvedPendingSourceExcludesOnlyItsExactLane() { + VersionToken version = VersionToken.numeric(4); + LaneSnapshot mixed = lane("MIX", version, + occupied("MIX", 1, 2, "T-RES", "RES", "SKU"), empty("MIX", 2, 2)); + LaneSnapshot safe = lane("SAFE", VersionToken.numeric(5), + occupied("SAFE", 1, 2, "T-SAFE", "RES", "SKU"), empty("SAFE", 2, 2)); + when(repository.loadSummary("W1")).thenReturn(new com.ruoyi.algorithm.repository.WarehouseSummary( + "W1", 2, 4, 2, 2, 1, 0, 0)); + when(repository.pageCandidateLanes("W1", null, 100)).thenReturn(new LanePage(List.of( + new LaneCandidate("W1", "MIX", 2, 1, 1, false, false, version), + new LaneCandidate("W1", "SAFE", 2, 1, 1, false, false, VersionToken.numeric(5))), null)); + when(repository.loadLaneSnapshots("W1", List.of("MIX", "SAFE"))).thenReturn(List.of(mixed, safe)); + when(repository.loadPendingOutboundJobs("W1")).thenReturn(List.of(new com.ruoyi.algorithm.repository.PendingOutboundJob( + "J", "TASK", null, "RES", "SKU", "MIX-1", "W1", "MIX", "EXPLICIT", "3", 21, "2026"))); + + assertThat(service.planInbound("W1", inbound("I-PENDING")).plan().assignment().orElseThrow().laneCode()) + .isEqualTo("SAFE"); + } + + @Test + void unresolvedPendingProjectScopeDoesNotExcludeUnrelatedLanes() { + VersionToken version = VersionToken.numeric(4); + LaneSnapshot mixed = lane("MIX", version, + occupied("MIX", 1, 2, "T-RES", "RES", "SKU"), empty("MIX", 2, 2)); + when(repository.loadSummary("W1")).thenReturn(new com.ruoyi.algorithm.repository.WarehouseSummary( + "W1", 1, 2, 1, 1, 0, 0, 0)); + when(repository.pageCandidateLanes("W1", null, 100)).thenReturn(new LanePage(List.of( + new LaneCandidate("W1", "MIX", 2, 1, 1, false, false, version)), null)); + when(repository.loadLaneSnapshots("W1", List.of("MIX"))).thenReturn(List.of(mixed)); + when(repository.loadPendingOutboundJobs("W1")).thenReturn(List.of(new com.ruoyi.algorithm.repository.PendingOutboundJob( + "J", "TASK", null, "RES", "SKU", null, "W1", null, "UNRESOLVED", "3", 21, "2026"))); + + assertThat(service.planInbound("W1", inbound("I-UNRESOLVED")).plan().assignment()).isPresent(); + } + + @Test + void outboundPreservesWaitingAndErrorStatuses() { + OutboundRequest request = new OutboundRequest("O-WAIT", "T-SOURCE", null, null, + null, null, 1, true); + LaneSnapshot blocked = lane("SRC", VersionToken.numeric(1), + occupied("SRC", 1, 2, "T-SOURCE", "P", "SKU"), + occupied("SRC", 2, 2, "T-BLOCK", "P", "SKU")); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.exactTray("T-SOURCE"))) + .thenReturn(List.of(new OutboundStockMatch("S1", "SRC-1", "SRC", 1, + "T-SOURCE", "P", "SKU", "L", "2026-01-01 00:00:00", + Instant.parse("2026-01-01T00:00:00Z")))); + when(repository.loadLaneSnapshots("W1", List.of("SRC"))).thenReturn(List.of(blocked)); + when(repository.loadRelocationBuffers("W1", Set.of(1))).thenReturn(List.of()); + + assertThat(service.planOutbound("W1", request).status()).isEqualTo(OutboundPlanStatus.WAITING); + + OutboundRequest missing = new OutboundRequest("O-ERR", "MISSING", null, null, + null, null, 1, true); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.exactTray("MISSING"))) + .thenReturn(List.of()); + assertThat(service.planOutbound("W1", missing).status()).isEqualTo(OutboundPlanStatus.ERROR); + } + + @Test + void outboundPreservesReadyStatus() { + OutboundRequest request = new OutboundRequest("O-READY", "T-READY", null, null, + null, null, 1, true); + LaneSnapshot source = lane("READY", VersionToken.numeric(2), + occupied("READY", 1, 1, "T-READY", "P", "SKU")); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.exactTray("T-READY"))) + .thenReturn(List.of(new OutboundStockMatch("S2", "READY-1", "READY", 1, + "T-READY", "P", "SKU", "L", "2026-01-01 00:00:00", + Instant.parse("2026-01-01T00:00:00Z")))); + when(repository.loadLaneSnapshots("W1", List.of("READY"))).thenReturn(List.of(source)); + when(repository.loadRelocationBuffers("W1", Set.of(1))).thenReturn(List.of()); + + assertThat(service.planOutbound("W1", request).status()).isEqualTo(OutboundPlanStatus.READY); + } + + @Test + void outboundDerivesCapacityModeFromWarehouseThresholds() { + OutboundRequest request = new OutboundRequest("O-CAP", "T-CAP", null, null, + null, null, 1, true); + LaneSnapshot source = lane("CAP", VersionToken.numeric(2), + occupied("CAP", 1, 1, "T-CAP", "P", "SKU")); + when(repository.loadSummary("W1")).thenReturn(new com.ruoyi.algorithm.repository.WarehouseSummary( + "W1", 615, 615, 600, 15, 0, 0, 0)); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.exactTray("T-CAP"))) + .thenReturn(List.of(new OutboundStockMatch("S", "CAP-1", "CAP", 1, + "T-CAP", "P", "SKU", "L", "2026-01-01T00:00:00Z", + Instant.parse("2026-01-01T00:00:00Z")))); + when(repository.loadLaneSnapshots("W1", List.of("CAP"))).thenReturn(List.of(source)); + when(repository.loadRelocationBuffers("W1", Set.of(1))).thenReturn(List.of()); + + assertThat(service.planOutbound("W1", request).assignment().orElseThrow().laneReleasing()).isTrue(); + } + + @Test + void outboundOtherOwnerDeepFloorWaitsEvenWhenBuffersAreSufficient() { + OutboundRequest request = new OutboundRequest("O-LOCK", "T-SOURCE", null, null, + null, null, 1, true); + LaneSnapshot blocked = lane("SRC", VersionToken.numeric(1), + occupied("SRC", 1, 2, "T-SOURCE", "P", "SKU"), + occupied("SRC", 2, 2, "T-BLOCK", "P", "SKU")); + SpaceSnapshot buffer = new SpaceSnapshot(new SpaceState("BUF", "CACHE", "BUF-L", 1, 1, 1, 1, 1, "1", + SpaceRole.RELOCATION_BUFFER, SpaceStatus.EMPTY, false, false, null, null, null, null, + null, null, false, null), List.of(), Set.of(), false, false, null); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.exactTray("T-SOURCE"))) + .thenReturn(List.of(new OutboundStockMatch("S1", "SRC-1", "SRC", 1, + "T-SOURCE", "P", "SKU", "L", "2026-01-01T00:00:00Z", + Instant.parse("2026-01-01T00:00:00Z")))); + when(repository.loadLaneSnapshots("W1", List.of("SRC"))).thenReturn(List.of(blocked)); + when(repository.loadRelocationBuffers("W1", Set.of(1))).thenReturn(List.of(buffer)); + when(repository.loadActiveDeepWorkflowFloors("W1", "O-LOCK")).thenReturn(Set.of(1)); + + assertThat(service.planOutbound("W1", request).status()).isEqualTo(OutboundPlanStatus.WAITING); + } + + @Test + void outboundSelfOwnedDeepFloorDoesNotWait() { + OutboundRequest request = new OutboundRequest("O-SELF", "T-SOURCE", null, null, + null, null, 1, true); + LaneSnapshot blocked = lane("SRC", VersionToken.numeric(1), + occupied("SRC", 1, 2, "T-SOURCE", "P", "SKU"), + occupied("SRC", 2, 2, "T-BLOCK", "P", "SKU")); + SpaceSnapshot buffer = new SpaceSnapshot(new SpaceState("BUF", "CACHE", "BUF-L", 1, 1, 1, 1, 1, "1", + SpaceRole.RELOCATION_BUFFER, SpaceStatus.EMPTY, false, false, null, null, null, null, + null, null, false, null), List.of(), Set.of(), false, false, null); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.exactTray("T-SOURCE"))) + .thenReturn(List.of(new OutboundStockMatch("S1", "SRC-1", "SRC", 1, + "T-SOURCE", "P", "SKU", "L", "2026-01-01T00:00:00Z", + Instant.parse("2026-01-01T00:00:00Z")))); + when(repository.loadLaneSnapshots("W1", List.of("SRC"))).thenReturn(List.of(blocked)); + when(repository.loadRelocationBuffers("W1", Set.of(1))).thenReturn(List.of(buffer)); + when(repository.loadActiveDeepWorkflowFloors("W1", "O-SELF")).thenReturn(Set.of()); + + assertThat(service.planOutbound("W1", request).status()).isEqualTo(OutboundPlanStatus.READY); + verify(repository).loadActiveDeepWorkflowFloors("W1", "O-SELF"); + } + + @Test + void outboundMissingScopeRemainsPlannerErrorInsteadOfThrowing() { + OutboundRequest request = new OutboundRequest("O-SCOPE", null, null, null, + null, null, 1, true); + + assertThat(service.planOutbound("W1", request).status()).isEqualTo(OutboundPlanStatus.ERROR); + } + + @Test + void exactTrayFifoLoadsProjectScopeSoRankIsGlobal() { + OutboundRequest request = new OutboundRequest("O-FIFO", "T-NEW", null, null, + "STRICT", 0, 1, true); + OutboundStockMatch selected = new OutboundStockMatch("S-NEW", "NEW-1", "NEW", 1, + "T-NEW", "P", "SKU", "L2", "2026-01-02T00:00:00Z", + Instant.parse("2026-01-02T00:00:00Z")); + OutboundStockMatch oldest = new OutboundStockMatch("S-OLD", "OLD-1", "OLD", 1, + "T-OLD", "P", "SKU", "L1", "2026-01-01T00:00:00Z", + Instant.parse("2026-01-01T00:00:00Z")); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.exactTray("T-NEW"))) + .thenReturn(List.of(selected)); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.project("P", "SKU"))) + .thenReturn(List.of(oldest, selected)); + when(repository.loadLaneSnapshots("W1", List.of("NEW", "OLD"))).thenReturn(List.of( + lane("NEW", VersionToken.numeric(2), occupiedAt("NEW", "T-NEW", "P", "SKU", "2026-01-02T00:00:00Z")), + lane("OLD", VersionToken.numeric(3), occupiedAt("OLD", "T-OLD", "P", "SKU", "2026-01-01T00:00:00Z")))); + when(repository.loadRelocationBuffers("W1", Set.of(1))).thenReturn(List.of()); + + var plan = service.planOutbound("W1", request); + + assertThat(plan.assignment().orElseThrow().fifo().fifoRank()).isEqualTo(2); + assertThat(plan.assignment().orElseThrow().fifo().fifoViolation()).isTrue(); + } + + @Test + void exactTrayScopeAggregatesNullAndValidDetailsBeforeProjectSearch() { + OutboundRequest request = new OutboundRequest("O-SCOPE-AGG", "T", null, null, + "STRICT", 0, 1, true); + OutboundStockMatch missing = new OutboundStockMatch("S0", "L-1", "L", 1, + "T", null, null, "L", "2026-01-01T00:00:00Z", Instant.parse("2026-01-01T00:00:00Z")); + OutboundStockMatch valid = new OutboundStockMatch("S1", "L-1", "L", 1, + "T", "P", "SKU", "L", "2026-01-01T00:00:00Z", Instant.parse("2026-01-01T00:00:00Z")); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.exactTray("T"))) + .thenReturn(List.of(missing, valid)); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.project("P", "SKU"))) + .thenReturn(List.of(valid)); + when(repository.loadLaneSnapshots("W1", List.of("L"))).thenReturn(List.of(lane("L", VersionToken.numeric(1), + occupiedAt("L", "T", "P", "SKU", "2026-01-01T00:00:00Z")))); + when(repository.loadRelocationBuffers("W1", Set.of(1))).thenReturn(List.of()); + + assertThat(service.planOutbound("W1", request).status()).isEqualTo(OutboundPlanStatus.READY); + verify(repository).searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.project("P", "SKU")); + } + + @Test + void exactTrayAmbiguousProjectsDoNotInventFifoScope() { + OutboundRequest request = new OutboundRequest("O-AMB", "T", null, null, + "STRICT", 0, 1, true); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.exactTray("T"))) + .thenReturn(List.of( + new OutboundStockMatch("S1", "L-1", "L", 1, "T", "P1", "SKU", "L", "2026-01-01T00:00:00Z", Instant.parse("2026-01-01T00:00:00Z")), + new OutboundStockMatch("S2", "L-1", "L", 1, "T", "P2", "SKU", "L", "2026-01-01T00:00:00Z", Instant.parse("2026-01-01T00:00:00Z")))); + var plan = service.planOutbound("W1", request); + + assertThat(plan.error().orElseThrow().code()).isEqualTo(OutboundErrorCode.AMBIGUOUS_TRAY); + verify(repository, never()).loadLaneSnapshots(any(), any()); + } + + @Test + void exactTrayInMultipleSpacesReturnsExplicitAmbiguityError() { + OutboundRequest request = new OutboundRequest("O-AMB-SPACE", "T", null, null, + null, null, 1, true); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.exactTray("T"))) + .thenReturn(List.of( + new OutboundStockMatch("S1", "L1-1", "L1", 1, "T", "P", "SKU", "L", "2026-01-01T00:00:00Z", Instant.parse("2026-01-01T00:00:00Z")), + new OutboundStockMatch("S2", "L2-1", "L2", 1, "T", "P", "SKU", "L", "2026-01-01T00:00:00Z", Instant.parse("2026-01-01T00:00:00Z")))); + + var plan = service.planOutbound("W1", request); + + assertThat(plan.error().orElseThrow().code()).isEqualTo(OutboundErrorCode.AMBIGUOUS_TRAY); + verify(repository, never()).loadLaneSnapshots(any(), any()); + } + + @Test + void exactTrayWithMultipleProductDetailsPlansTheWholePallet() { + OutboundRequest request = new OutboundRequest("O-AMB-PRODUCT", "T", null, null, + null, null, 1, true); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.exactTray("T"))) + .thenReturn(List.of( + new OutboundStockMatch("S1", "L-1", "L", 1, "T", "P", "SKU-1", "L", "2026-01-01T00:00:00Z", Instant.parse("2026-01-01T00:00:00Z")), + new OutboundStockMatch("S2", "L-1", "L", 1, "T", "P", "SKU-2", "L", "2026-01-01T00:00:00Z", Instant.parse("2026-01-01T00:00:00Z")))); + when(repository.loadLaneSnapshots("W1", List.of("L"))).thenReturn(List.of(lane("L", VersionToken.numeric(1), + occupiedAt("L", "T", "P", null, "2026-01-01T00:00:00Z")))); + when(repository.loadRelocationBuffers("W1", Set.of(1))).thenReturn(List.of()); + + var plan = service.planOutbound("W1", request); + + assertThat(plan.status()).isEqualTo(OutboundPlanStatus.READY); + assertThat(plan.assignment().orElseThrow().trayNo()).isEqualTo("T"); + } + + @Test + void productFilterNormalizesOnlyRepositoryMatchedPallets() { + OutboundRequest request = new OutboundRequest("O-PRODUCT", null, "P", "SKU-2", + null, null, 1, true); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.project("P", "SKU-2"))) + .thenReturn(List.of(new OutboundStockMatch("S2", "L-1", "L", 1, + "T", "P", "SKU-2", "L2", "2026-01-02T00:00:00Z", + Instant.parse("2026-01-02T00:00:00Z")))); + when(repository.loadLaneSnapshots("W1", List.of("L"))).thenReturn(List.of(lane("L", VersionToken.numeric(1), + occupiedAt("L", "T", "P", null, "2026-01-01T00:00:00Z")))); + when(repository.loadRelocationBuffers("W1", Set.of(1))).thenReturn(List.of()); + + var plan = service.planOutbound("W1", request); + + assertThat(plan.status()).isEqualTo(OutboundPlanStatus.READY); + assertThat(plan.assignment().orElseThrow().productId()).isEqualTo("SKU-2"); + } + + @Test + void exactMultiProductTrayFifoUsesWholeProjectScope() { + OutboundRequest request = new OutboundRequest("O-MULTI-FIFO", "T-NEW", null, null, + "STRICT", 0, 1, true); + List exact = List.of( + new OutboundStockMatch("S-NEW-1", "NEW-1", "NEW", 1, "T-NEW", "P", "SKU-1", "L1", + "2026-01-02T00:00:00Z", Instant.parse("2026-01-02T00:00:00Z")), + new OutboundStockMatch("S-NEW-2", "NEW-1", "NEW", 1, "T-NEW", "P", "SKU-2", "L2", + "2026-01-02T00:00:00Z", Instant.parse("2026-01-02T00:00:00Z"))); + OutboundStockMatch oldest = new OutboundStockMatch("S-OLD", "OLD-1", "OLD", 1, + "T-OLD", "P", "SKU-3", "L0", "2026-01-01T00:00:00Z", + Instant.parse("2026-01-01T00:00:00Z")); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.exactTray("T-NEW"))) + .thenReturn(exact); + when(repository.searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.project("P", null))) + .thenReturn(List.of(oldest, exact.get(0), exact.get(1))); + when(repository.loadLaneSnapshots("W1", List.of("NEW", "OLD"))).thenReturn(List.of( + lane("NEW", VersionToken.numeric(2), occupiedAt("NEW", "T-NEW", "P", null, "2026-01-02T00:00:00Z")), + lane("OLD", VersionToken.numeric(3), occupiedAt("OLD", "T-OLD", "P", null, "2026-01-01T00:00:00Z")))); + when(repository.loadRelocationBuffers("W1", Set.of(1))).thenReturn(List.of()); + + var plan = service.planOutbound("W1", request); + + assertThat(plan.status()).isEqualTo(OutboundPlanStatus.READY); + assertThat(plan.assignment().orElseThrow().fifo().fifoRank()).isEqualTo(2); + verify(repository).searchOutboundStock("W1", com.ruoyi.algorithm.repository.OutboundStockSearch.project("P", null)); + } + + @Test + void exposesSummaryDiagnosticsAndTidyThroughPlainMethods() { + var summary = new com.ruoyi.algorithm.repository.WarehouseSummary("W1", 0, 0, 0, 0, 0, 0, 0); + when(repository.loadSummary("W1")).thenReturn(summary); + when(repository.pageWarehouseLanes("W1", null, 100)).thenReturn(new LanePage(List.of(), null)); + + assertThat(service.summary("W1")).isEqualTo(summary); + assertThat(service.diagnostics("W1").issues()).isEmpty(); + assertThat(service.planTidy("W1", Instant.parse("2026-07-20T00:00:00Z")).candidates()).isEmpty(); + } + + @Test + void tidyUsesPendingProjectAndProductScope() { + VersionToken version = VersionToken.numeric(1); + LaneSnapshot source = lane("GUEST", version, + occupied("GUEST", 1, 3, "T-R", "R", "SKU-R"), + occupied("GUEST", 2, 3, "T-G", "G", "SKU-G"), empty("GUEST", 3, 3)); + LaneSnapshot target = lane("HOME", version, + occupied("HOME", 1, 3, "T-H", "G", "SKU-G"), empty("HOME", 2, 3), empty("HOME", 3, 3)); + when(repository.pageWarehouseLanes("W1", null, 100)).thenReturn(new LanePage(List.of( + new LaneCandidate("W1", "GUEST", 3, 2, 1, false, false, version), + new LaneCandidate("W1", "HOME", 3, 1, 2, false, false, version)), null)); + when(repository.loadLaneSnapshots("W1", List.of("GUEST", "HOME"))).thenReturn(List.of(source, target)); + when(repository.loadPendingOutboundJobs("W1")).thenReturn(List.of(new com.ruoyi.algorithm.repository.PendingOutboundJob( + "J", "T", null, "G", "SKU-G", null, "W1", null, "UNRESOLVED", "3", 21, "2026"))); + + assertThat(service.planTidy("W1", Instant.parse("2026-07-20T00:00:00Z")).candidates()).isEmpty(); + } + + @Test + void explicitReserveMapsSnapshotConflictToReplanRequired() { + VersionToken version = VersionToken.numeric(9); + LaneSnapshot lane = lane("L1", version, empty("L1", 1, 2), empty("L1", 2, 2)); + InboundPlanningResult planned = new InboundPlanningResult( + new InboundPlanner().plan(inbound("I-RESERVE"), new com.ruoyi.algorithm.inbound.InboundContext( + lane.spaceStates(), RepositoryPolicy.defaults().inboundPolicy(), List.of(), 0)), version); + when(repository.tryReserveInbound(any())).thenReturn(ReservationResult.conflict("LANE_VERSION_MISMATCH", "R1")); + + InboundReservationOutcome outcome = service.reserveInbound("R1", "W1", "P", planned); + + assertThat(outcome.resultCode()).isEqualTo("REPLAN_REQUIRED"); + verify(repository).tryReserveInbound(new InboundReservation("R1", "W1", "L1", "L1-1", "P", version)); + } + + private InboundRequest inbound(String id) { + return new InboundRequest(id, "T-IN", "P", "SKU", "L", 2, 1, null, Set.of(), BatchLaneMode.OPEN); + } + + private LaneSnapshot lane(String code, VersionToken version, SpaceState... spaces) { + return new LaneSnapshot("W1", code, version, List.of(spaces).stream() + .map(space -> new SpaceSnapshot(space, List.of(), Set.of(), space.availableEmpty(), false, null)).toList()); + } + + private SpaceState empty(String lane, int depth, int capacity) { + return state(lane, depth, capacity, SpaceStatus.EMPTY, null, null, null); + } + + private SpaceState emptyAtFloor(String lane, int depth, int capacity, int floor) { + SpaceState value = empty(lane, depth, capacity); + return new SpaceState(value.spaceId(), value.zoneCode(), value.laneCode(), value.depthOrder(), + value.laneCapacity(), floor, value.aisleNo(), value.groupCoding(), value.rowCode(), value.role(), + value.status(), value.outboundTaskActive(), value.inventoryProjectConflict(), value.trayNo(), + value.projectNo(), value.productId(), value.lotNo(), value.inboundAt(), value.outboundAt(), + value.reserved(), value.rowVersion()); + } + + private SpaceState occupied(String lane, int depth, int capacity, String tray, String project, String product) { + return state(lane, depth, capacity, SpaceStatus.OCCUPIED, tray, project, product); + } + + private SpaceState occupiedAt(String lane, String tray, String project, String product, String inboundAt) { + SpaceState value = state(lane, 1, 1, SpaceStatus.OCCUPIED, tray, project, product); + return new SpaceState(value.spaceId(), value.zoneCode(), value.laneCode(), value.depthOrder(), + value.laneCapacity(), value.floorNo(), value.aisleNo(), value.groupCoding(), value.rowCode(), + value.role(), value.status(), value.outboundTaskActive(), value.inventoryProjectConflict(), + value.trayNo(), value.projectNo(), value.productId(), value.lotNo(), Instant.parse(inboundAt), + value.outboundAt(), value.reserved(), value.rowVersion()); + } + + private SpaceState state(String lane, int depth, int capacity, SpaceStatus status, + String tray, String project, String product) { + return new SpaceState(lane + "-" + depth, "A", lane, depth, capacity, 1, 1, depth, "R", + SpaceRole.STORAGE, status, false, false, tray, project, product, "L", + Instant.parse("2026-01-01T00:00:00Z"), null, false, null); + } +} diff --git a/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/tidy/TidyPlannerTest.java b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/tidy/TidyPlannerTest.java new file mode 100644 index 0000000..6890df7 --- /dev/null +++ b/fortucky-algorithm/src/test/java/com/ruoyi/algorithm/tidy/TidyPlannerTest.java @@ -0,0 +1,284 @@ +package com.ruoyi.algorithm.tidy; + +import com.ruoyi.algorithm.model.SpaceRole; +import com.ruoyi.algorithm.model.SpaceState; +import com.ruoyi.algorithm.model.SpaceStatus; +import com.ruoyi.algorithm.policy.SchedulingPolicy; +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; + +class TidyPlannerTest { + + private final TidyPlanner planner = new TidyPlanner(); + + @Test + void returnsGuestFromOutsideToInsideWithoutMutatingCurrentInventory() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("SHARED", 5, + stock(1, "HOST-1", "HOST", old()), stock(2, "HOST-2", "HOST", old()), + stock(3, "GUEST-3", "GUEST", old()), stock(4, "GUEST-4", "GUEST", old()), empty(5))); + spaces.addAll(lane("OWN", 5, + stock(1, "OWN-1", "GUEST", old()), empty(2), empty(3), empty(4), empty(5))); + + TidyPlan result = plan(spaces, List.of(), null, SchedulingPolicy.ft546Defaults()); + TidyCandidate candidate = result.candidates().stream() + .filter(item -> item.type() == TidyCandidateType.GUEST_RETURN).findFirst().orElseThrow(); + + assertThat(candidate.moves()).containsExactly( + new TidyMove("GUEST-4", "SHARED-4", "OWN-2"), + new TidyMove("GUEST-3", "SHARED-3", "OWN-3")); + assertThat(spaces.stream().filter(space -> space.laneCode().equals("SHARED")) + .map(SpaceState::trayNo)).containsExactly("HOST-1", "HOST-2", "GUEST-3", "GUEST-4", null); + } + + @Test + void pendingTrayProtectsItsWholeSourceLaneFromTidy() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("SHARED", 5, + stock(1, "HOST-1", "HOST", old()), stock(2, "GUEST-2", "GUEST", old()), + empty(3), empty(4), empty(5))); + spaces.addAll(lane("OWN", 5, + stock(1, "OWN-1", "GUEST", old()), empty(2), empty(3), empty(4), empty(5))); + + TidyPlan result = plan(spaces, + List.of(new TidyPendingOutbound(null, null, "HOST-1", null)), null, + SchedulingPolicy.ft546Defaults()); + + assertThat(result.candidates()).noneMatch(candidate -> candidate.type() == TidyCandidateType.GUEST_RETURN); + } + + @Test + void downgradeMergeMovesOutermostFirstAndOnlyUsesStagnantCurrentStock() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("DEEP", 5, + stock(1, "D-1", "P", "2026-07-01T00:00:00Z"), + stock(2, "D-2", "P", "2026-07-01T01:00:00Z"), empty(3), empty(4), empty(5))); + spaces.addAll(lane("SHALLOW", 2, empty(1), empty(2))); + + TidyPlan stale = plan(spaces, List.of(), Instant.parse("2026-07-10T00:00:00Z"), + SchedulingPolicy.ft546Defaults()); + TidyPlan fresh = plan(spaces, List.of(), Instant.parse("2026-07-02T00:00:00Z"), + SchedulingPolicy.ft546Defaults()); + TidyCandidate downgrade = stale.candidates().stream() + .filter(item -> item.type() == TidyCandidateType.DOWNGRADE_MERGE).findFirst().orElseThrow(); + + assertThat(downgrade.moves()).containsExactly( + new TidyMove("D-2", "DEEP-2", "SHALLOW-1"), + new TidyMove("D-1", "DEEP-1", "SHALLOW-2")); + assertThat(downgrade.releasesLaneCode()).contains("DEEP"); + assertThat(fresh.candidates()).noneMatch(item -> item.type() == TidyCandidateType.DOWNGRADE_MERGE); + } + + @Test + void onePalletDowngradePrefersFlexThenCacheSingleDepthWithoutRequiringDepthTwo() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("DEEP", 5, + stock(1, "D-1", "P", old()), empty(2), empty(3), empty(4), empty(5))); + spaces.addAll(lane("CACHE-POOL", 1, "CACHE", empty(1))); + spaces.addAll(lane("FLEX-POOL", 1, "FLEX", empty(1))); + + TidyCandidate downgrade = plan(spaces, List.of(), Instant.parse("2026-07-10T00:00:00Z"), + SchedulingPolicy.ft546Defaults()).candidates().stream() + .filter(item -> item.type() == TidyCandidateType.DOWNGRADE_MERGE).findFirst().orElseThrow(); + + assertThat(downgrade.moves()).containsExactly(new TidyMove("D-1", "DEEP-1", "FLEX-POOL-1")); + assertThat(downgrade.releasesLaneCode()).contains("DEEP"); + } + + @Test + void onePalletDowngradeFallsBackToEmptyDepthTwoWhenNoSinglePoolIsAvailable() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("DEEP", 5, + stock(1, "D-1", "P", old()), empty(2), empty(3), empty(4), empty(5))); + spaces.addAll(lane("DOUBLE", 2, empty(1), empty(2))); + + TidyCandidate downgrade = plan(spaces, List.of(), Instant.parse("2026-07-10T00:00:00Z"), + SchedulingPolicy.ft546Defaults()).candidates().stream() + .filter(item -> item.type() == TidyCandidateType.DOWNGRADE_MERGE).findFirst().orElseThrow(); + + assertThat(downgrade.moves()).containsExactly(new TidyMove("D-1", "DEEP-1", "DOUBLE-1")); + } + + @Test + void consolidatesAccessibleShallowStockIntoADeepProjectLaneAndYieldsToPendingLane() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("DEEP", 5, + stock(1, "D-1", "P", old()), stock(2, "D-2", "P", old()), empty(3), empty(4), empty(5))); + spaces.addAll(lane("SHALLOW", 2, + stock(1, "S-1", "P", old()), stock(2, "S-2", "P", old()))); + + TidyCandidate consolidate = plan(spaces, List.of(), null, SchedulingPolicy.ft546Defaults()) + .candidates().stream() + .filter(item -> item.type() == TidyCandidateType.CONSOLIDATE_INCUBATION).findFirst().orElseThrow(); + + assertThat(consolidate.moves()).containsExactly( + new TidyMove("S-2", "SHALLOW-2", "DEEP-3"), + new TidyMove("S-1", "SHALLOW-1", "DEEP-4")); + assertThat(consolidate.releasesLaneCode()).contains("SHALLOW"); + + TidyPlan yielded = plan(spaces, List.of(new TidyPendingOutbound(null, null, null, "DEEP")), + null, SchedulingPolicy.ft546Defaults()); + assertThat(yielded.candidates()) + .noneMatch(item -> item.type() == TidyCandidateType.CONSOLIDATE_INCUBATION); + } + + @Test + void sortsCandidateTypesAndCapsTheResultAtPolicyMaximum() { + List spaces = new ArrayList<>(); + for (int index = 1; index <= 3; index++) { + spaces.addAll(lane("SHARED-" + index, 2, + stock(1, "H-" + index, "H" + index, old()), + stock(2, "G-" + index, "G" + index, old()))); + spaces.addAll(lane("OWN-" + index, 2, + stock(1, "O-" + index, "G" + index, old()), empty(2))); + } + SchedulingPolicy capped = new SchedulingPolicy(0.55, 0.45, 564, 597, 615, 4, 2, 1); + + TidyPlan result = plan(spaces, List.of(), null, capped); + + assertThat(result.candidates()).hasSize(1); + assertThat(result.candidates().get(0).type()).isEqualTo(TidyCandidateType.GUEST_RETURN); + assertThat(result.diagnostics()).anyMatch(message -> message.contains("1")); + } + + @Test + void laterCandidatesDoNotReuseALaneAlreadyChangedByAnEarlierCandidate() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("DEEP", 5, + stock(1, "D-1", "P", old()), stock(2, "D-2", "P", old()), + empty(3), empty(4), empty(5))); + spaces.addAll(lane("A-EMPTY", 2, empty(1), empty(2))); + spaces.addAll(lane("SHALLOW", 2, + stock(1, "S-1", "P", old()), stock(2, "S-2", "P", old()))); + + TidyPlan result = plan(spaces, List.of(), Instant.parse("2026-07-10T00:00:00Z"), + SchedulingPolicy.ft546Defaults()); + + assertThat(result.candidates()).anyMatch(item -> item.type() == TidyCandidateType.DOWNGRADE_MERGE); + assertThat(result.candidates()).noneMatch(item -> item.type() == TidyCandidateType.CONSOLIDATE_INCUBATION); + } + + @Test + void guestReturnFallsBackToAnEmptyGradedLaneWhenNoResidentLaneExists() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("SHARED", 3, + stock(1, "HOST", "HOST", old()), + stock(2, "G-2", "GUEST", old()), stock(3, "G-3", "GUEST", old()))); + spaces.addAll(lane("EMPTY-2", 2, empty(1), empty(2))); + spaces.addAll(lane("EMPTY-5", 5, empty(1), empty(2), empty(3), empty(4), empty(5))); + + TidyCandidate candidate = plan(spaces, List.of(), null, SchedulingPolicy.ft546Defaults()) + .candidates().stream() + .filter(item -> item.type() == TidyCandidateType.GUEST_RETURN).findFirst().orElseThrow(); + + assertThat(candidate.moves()).containsExactly( + new TidyMove("G-3", "SHARED-3", "EMPTY-5-1"), + new TidyMove("G-2", "SHARED-2", "EMPTY-5-2")); + } + + @Test + void downgradeStalenessUsesNewestProjectStockAcrossTheWholeWarehouse() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("DEEP", 5, + stock(1, "D-1", "P", old()), stock(2, "D-2", "P", old()), + empty(3), empty(4), empty(5))); + spaces.addAll(lane("RECENT", 1, + stock(1, "RECENT-1", "P", "2026-07-09T00:00:00Z"))); + spaces.addAll(lane("EMPTY", 2, empty(1), empty(2))); + + TidyPlan result = plan(spaces, List.of(), Instant.parse("2026-07-10T00:00:00Z"), + SchedulingPolicy.ft546Defaults()); + + assertThat(result.candidates()).noneMatch(item -> item.type() == TidyCandidateType.DOWNGRADE_MERGE); + } + + @Test + void guestReturnTargetLaneIsNotReusedAsAConsolidationSource() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("SHARED", 2, + stock(1, "HOST", "HOST", old()), stock(2, "GUEST", "P", old()))); + spaces.addAll(lane("A-OWN-SHALLOW", 2, + stock(1, "OWN", "P", old()), empty(2))); + spaces.addAll(lane("Z-DEEP", 5, + stock(1, "DEEP-1", "P", old()), empty(2), empty(3), empty(4), empty(5))); + + TidyPlan result = plan(spaces, List.of(), null, SchedulingPolicy.ft546Defaults()); + TidyCandidate guest = result.candidates().stream() + .filter(item -> item.type() == TidyCandidateType.GUEST_RETURN).findFirst().orElseThrow(); + + assertThat(guest.moves()).containsExactly(new TidyMove("GUEST", "SHARED-2", "A-OWN-SHALLOW-2")); + assertThat(result.candidates()).noneMatch(item -> item.type() == TidyCandidateType.CONSOLIDATE_INCUBATION + && item.moves().stream().anyMatch(move -> move.fromSpaceId().startsWith("A-OWN-SHALLOW-"))); + } + + @Test + void commonProjectsAreExcludedFromDowngradeAndConsolidation() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("COMMON-DEEP", 5, + stock(1, "C-D1", "COMMON-X", old()), stock(2, "C-D2", "COMMON-X", old()), + empty(3), empty(4), empty(5))); + spaces.addAll(lane("COMMON-SHALLOW", 2, + stock(1, "C-S1", "COMMON-X", old()), stock(2, "C-S2", "COMMON-X", old()))); + spaces.addAll(lane("EMPTY", 2, empty(1), empty(2))); + + TidyPlan result = planner.plan(new TidyRequest(spaces, List.of(), + Instant.parse("2026-07-10T00:00:00Z"), SchedulingPolicy.ft546Defaults(), Set.of("COMMON-X"))); + + assertThat(result.candidates()).noneMatch(item -> item.type() == TidyCandidateType.DOWNGRADE_MERGE); + assertThat(result.candidates()).noneMatch(item -> item.type() == TidyCandidateType.CONSOLIDATE_INCUBATION); + } + + @Test + void ignoresOccupiedSpaceWithoutProjectWhenBuildingLaneSegments() { + List spaces = new ArrayList<>(); + spaces.addAll(lane("UNKNOWN", 2, + stock(1, "UNKNOWN-1", null, old()), empty(2))); + + assertThatCode(() -> planner.plan(new TidyRequest(spaces, List.of(), null, + SchedulingPolicy.ft546Defaults(), Set.of()))) + .doesNotThrowAnyException(); + } + + private TidyPlan plan(List spaces, List pending, + Instant now, SchedulingPolicy policy) { + return planner.plan(new TidyRequest(spaces, pending, now, policy)); + } + + private List lane(String code, int capacity, Slot... slots) { + return lane(code, capacity, "MAIN", slots); + } + + private List lane(String code, int capacity, String zone, Slot... slots) { + List spaces = new ArrayList<>(); + for (Slot slot : slots) { + spaces.add(new SpaceState(code + "-" + slot.depth(), zone, code, slot.depth(), capacity, + 1, 6, slot.depth(), "1", SpaceRole.STORAGE, slot.status(), false, false, + slot.tray(), slot.project(), "M", "LOT", + slot.inboundTime() == null ? null : Instant.parse(slot.inboundTime()), + null, false, "rv")); + } + return spaces; + } + + private Slot stock(int depth, String tray, String project, String time) { + return new Slot(depth, SpaceStatus.OCCUPIED, tray, project, time); + } + + private Slot empty(int depth) { + return new Slot(depth, SpaceStatus.EMPTY, null, null, null); + } + + private String old() { + return "2026-07-01T00:00:00Z"; + } + + private record Slot(int depth, SpaceStatus status, String tray, String project, String inboundTime) { + } +} diff --git a/fortucky-algorithm/src/test/resources/contracts/js-contract-fixtures.json b/fortucky-algorithm/src/test/resources/contracts/js-contract-fixtures.json new file mode 100644 index 0000000..152cfe2 --- /dev/null +++ b/fortucky-algorithm/src/test/resources/contracts/js-contract-fixtures.json @@ -0,0 +1,55844 @@ +{ + "sourceAlgorithmVersion": "1.2.0", + "sourceSha256": "61fc21daaa46e942b0bca45c71e8a1bab6dc8266cb1084d597c37255c7bfae08", + "fixtures": [ + { + "id": "capacity-inbound", + "kind": "INBOUND", + "policy": { + "capacityWeight": 0.9, + "efficiencyWeight": 0.1 + }, + "request": { + "requestId": "IN-CAPACITY", + "trayNo": "TRAY-CAPACITY", + "projectNo": "P-NEW", + "productId": "M-NEW", + "lotNo": null, + "expectedProjectPallets": null, + "entryFloor": 1, + "targetFloor": null, + "batchLaneMode": "OPEN" + }, + "spaces": [ + { + "spaceId": "020501", + "zoneCode": "FLEX", + "laneCode": "A0201", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030301", + "zoneCode": "FLEX", + "laneCode": "A0301", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "OPEN-NEAR", + "projectNo": "P-NEW", + "productId": "M-OLD", + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030401", + "zoneCode": "FLEX", + "laneCode": "A0301", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030501", + "zoneCode": "FLEX", + "laneCode": "A0301", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031101", + "zoneCode": "CACHE", + "laneCode": "B0301", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040301", + "zoneCode": "FLEX", + "laneCode": "A0401", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040401", + "zoneCode": "FLEX", + "laneCode": "A0401", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040501", + "zoneCode": "FLEX", + "laneCode": "A0401", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041101", + "zoneCode": "CACHE", + "laneCode": "B0401", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050301", + "zoneCode": "FLEX", + "laneCode": "A0501", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050401", + "zoneCode": "FLEX", + "laneCode": "A0501", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050501", + "zoneCode": "FLEX", + "laneCode": "A0501", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051101", + "zoneCode": "CACHE", + "laneCode": "B0501", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060301", + "zoneCode": "FLEX", + "laneCode": "A0601", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060401", + "zoneCode": "FLEX", + "laneCode": "A0601", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060501", + "zoneCode": "FLEX", + "laneCode": "A0601", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061101", + "zoneCode": "CACHE", + "laneCode": "B0601", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070101", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070201", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070301", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070401", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070501", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071101", + "zoneCode": "CACHE", + "laneCode": "B0701", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080101", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080201", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080301", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080401", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080501", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080701", + "zoneCode": "FLEX", + "laneCode": "C0801", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080801", + "zoneCode": "FLEX", + "laneCode": "C0801", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080901", + "zoneCode": "RESERVE", + "laneCode": "D0801", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081101", + "zoneCode": "CACHE", + "laneCode": "B0801", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090101", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090201", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090301", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090401", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090501", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090701", + "zoneCode": "FLEX", + "laneCode": "C0901", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090801", + "zoneCode": "FLEX", + "laneCode": "C0901", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090901", + "zoneCode": "RESERVE", + "laneCode": "D0901", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091101", + "zoneCode": "CACHE", + "laneCode": "B0901", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100101", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100201", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100301", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100401", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100501", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100701", + "zoneCode": "FLEX", + "laneCode": "C1001", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100801", + "zoneCode": "FLEX", + "laneCode": "C1001", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100901", + "zoneCode": "RESERVE", + "laneCode": "D1001", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101101", + "zoneCode": "CACHE", + "laneCode": "B1001", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110101", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110201", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110301", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110401", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110501", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110701", + "zoneCode": "FLEX", + "laneCode": "C1101", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110801", + "zoneCode": "FLEX", + "laneCode": "C1101", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110901", + "zoneCode": "RESERVE", + "laneCode": "D1101", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111101", + "zoneCode": "CACHE", + "laneCode": "B1101", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120101", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120201", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120301", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120401", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120501", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120701", + "zoneCode": "FLEX", + "laneCode": "C1201", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120801", + "zoneCode": "FLEX", + "laneCode": "C1201", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120901", + "zoneCode": "RESERVE", + "laneCode": "D1201", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121101", + "zoneCode": "CACHE", + "laneCode": "B1201", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130101", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130201", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130301", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130401", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130501", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130701", + "zoneCode": "FLEX", + "laneCode": "C1301", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130801", + "zoneCode": "FLEX", + "laneCode": "C1301", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130901", + "zoneCode": "FLEX", + "laneCode": "D1301", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131101", + "zoneCode": "RESERVE", + "laneCode": "B1301", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140101", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140201", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140301", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140401", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140501", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141101", + "zoneCode": "RESERVE", + "laneCode": "B1401", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020502", + "zoneCode": "FLEX", + "laneCode": "A0202", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030302", + "zoneCode": "FLEX", + "laneCode": "A0302", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030402", + "zoneCode": "FLEX", + "laneCode": "A0302", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030502", + "zoneCode": "FLEX", + "laneCode": "A0302", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031102", + "zoneCode": "CACHE", + "laneCode": "B0302", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040302", + "zoneCode": "FLEX", + "laneCode": "A0402", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040402", + "zoneCode": "FLEX", + "laneCode": "A0402", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040502", + "zoneCode": "FLEX", + "laneCode": "A0402", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041102", + "zoneCode": "CACHE", + "laneCode": "B0402", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050302", + "zoneCode": "FLEX", + "laneCode": "A0502", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050402", + "zoneCode": "FLEX", + "laneCode": "A0502", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050502", + "zoneCode": "FLEX", + "laneCode": "A0502", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051102", + "zoneCode": "CACHE", + "laneCode": "B0502", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060302", + "zoneCode": "FLEX", + "laneCode": "A0602", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060402", + "zoneCode": "FLEX", + "laneCode": "A0602", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060502", + "zoneCode": "FLEX", + "laneCode": "A0602", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061102", + "zoneCode": "CACHE", + "laneCode": "B0602", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070102", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070202", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070302", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070402", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070502", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071102", + "zoneCode": "CACHE", + "laneCode": "B0702", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080102", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080202", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080302", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080402", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080502", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080702", + "zoneCode": "FLEX", + "laneCode": "C0802", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080802", + "zoneCode": "FLEX", + "laneCode": "C0802", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080902", + "zoneCode": "RESERVE", + "laneCode": "D0802", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081102", + "zoneCode": "CACHE", + "laneCode": "B0802", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090102", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090202", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090302", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090402", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090502", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090702", + "zoneCode": "FLEX", + "laneCode": "C0902", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090802", + "zoneCode": "FLEX", + "laneCode": "C0902", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090902", + "zoneCode": "RESERVE", + "laneCode": "D0902", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091102", + "zoneCode": "CACHE", + "laneCode": "B0902", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100102", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100202", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100302", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100402", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100502", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100702", + "zoneCode": "FLEX", + "laneCode": "C1002", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100802", + "zoneCode": "FLEX", + "laneCode": "C1002", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100902", + "zoneCode": "RESERVE", + "laneCode": "D1002", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101102", + "zoneCode": "CACHE", + "laneCode": "B1002", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110102", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110202", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110302", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110402", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110502", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110702", + "zoneCode": "FLEX", + "laneCode": "C1102", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110802", + "zoneCode": "FLEX", + "laneCode": "C1102", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110902", + "zoneCode": "RESERVE", + "laneCode": "D1102", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111102", + "zoneCode": "CACHE", + "laneCode": "B1102", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120102", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120202", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120302", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120402", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120502", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120702", + "zoneCode": "FLEX", + "laneCode": "C1202", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120802", + "zoneCode": "FLEX", + "laneCode": "C1202", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120902", + "zoneCode": "RESERVE", + "laneCode": "D1202", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121102", + "zoneCode": "CACHE", + "laneCode": "B1202", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130102", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130202", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130302", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130402", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130502", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130702", + "zoneCode": "FLEX", + "laneCode": "C1302", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130802", + "zoneCode": "FLEX", + "laneCode": "C1302", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130902", + "zoneCode": "FLEX", + "laneCode": "D1302", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131102", + "zoneCode": "RESERVE", + "laneCode": "B1302", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140102", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140202", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140302", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140402", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140502", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141102", + "zoneCode": "RESERVE", + "laneCode": "B1402", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020503", + "zoneCode": "FLEX", + "laneCode": "A0203", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030303", + "zoneCode": "FLEX", + "laneCode": "A0303", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030403", + "zoneCode": "FLEX", + "laneCode": "A0303", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030503", + "zoneCode": "FLEX", + "laneCode": "A0303", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031103", + "zoneCode": "CACHE", + "laneCode": "B0303", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040303", + "zoneCode": "FLEX", + "laneCode": "A0403", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040403", + "zoneCode": "FLEX", + "laneCode": "A0403", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040503", + "zoneCode": "FLEX", + "laneCode": "A0403", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041103", + "zoneCode": "CACHE", + "laneCode": "B0403", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050303", + "zoneCode": "FLEX", + "laneCode": "A0503", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050403", + "zoneCode": "FLEX", + "laneCode": "A0503", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050503", + "zoneCode": "FLEX", + "laneCode": "A0503", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051103", + "zoneCode": "CACHE", + "laneCode": "B0503", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060303", + "zoneCode": "FLEX", + "laneCode": "A0603", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060403", + "zoneCode": "FLEX", + "laneCode": "A0603", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060503", + "zoneCode": "FLEX", + "laneCode": "A0603", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061103", + "zoneCode": "CACHE", + "laneCode": "B0603", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070103", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070203", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070303", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070403", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070503", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071103", + "zoneCode": "CACHE", + "laneCode": "B0703", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080103", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080203", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080303", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080403", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080503", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080703", + "zoneCode": "FLEX", + "laneCode": "C0803", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080803", + "zoneCode": "FLEX", + "laneCode": "C0803", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080903", + "zoneCode": "RESERVE", + "laneCode": "D0803", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081103", + "zoneCode": "CACHE", + "laneCode": "B0803", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090103", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090203", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090303", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090403", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090503", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090703", + "zoneCode": "FLEX", + "laneCode": "C0903", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090803", + "zoneCode": "FLEX", + "laneCode": "C0903", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090903", + "zoneCode": "RESERVE", + "laneCode": "D0903", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091103", + "zoneCode": "CACHE", + "laneCode": "B0903", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100103", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100203", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100303", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100403", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100503", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100703", + "zoneCode": "FLEX", + "laneCode": "C1003", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100803", + "zoneCode": "FLEX", + "laneCode": "C1003", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100903", + "zoneCode": "RESERVE", + "laneCode": "D1003", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101103", + "zoneCode": "CACHE", + "laneCode": "B1003", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110103", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110203", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110303", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110403", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110503", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110703", + "zoneCode": "FLEX", + "laneCode": "C1103", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110803", + "zoneCode": "FLEX", + "laneCode": "C1103", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110903", + "zoneCode": "RESERVE", + "laneCode": "D1103", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111103", + "zoneCode": "CACHE", + "laneCode": "B1103", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120103", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120203", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120303", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120403", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120503", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120703", + "zoneCode": "FLEX", + "laneCode": "C1203", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120803", + "zoneCode": "FLEX", + "laneCode": "C1203", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120903", + "zoneCode": "RESERVE", + "laneCode": "D1203", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121103", + "zoneCode": "CACHE", + "laneCode": "B1203", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130103", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130203", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130303", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130403", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130503", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130703", + "zoneCode": "FLEX", + "laneCode": "C1303", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130803", + "zoneCode": "FLEX", + "laneCode": "C1303", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130903", + "zoneCode": "FLEX", + "laneCode": "D1303", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131103", + "zoneCode": "RESERVE", + "laneCode": "B1303", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140103", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140203", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140303", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140403", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140503", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141103", + "zoneCode": "RESERVE", + "laneCode": "B1403", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020504", + "zoneCode": "FLEX", + "laneCode": "A0204", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030304", + "zoneCode": "FLEX", + "laneCode": "A0304", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030404", + "zoneCode": "FLEX", + "laneCode": "A0304", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030504", + "zoneCode": "FLEX", + "laneCode": "A0304", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031104", + "zoneCode": "CACHE", + "laneCode": "B0304", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040304", + "zoneCode": "FLEX", + "laneCode": "A0404", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040404", + "zoneCode": "FLEX", + "laneCode": "A0404", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040504", + "zoneCode": "FLEX", + "laneCode": "A0404", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041104", + "zoneCode": "CACHE", + "laneCode": "B0404", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050304", + "zoneCode": "FLEX", + "laneCode": "A0504", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050404", + "zoneCode": "FLEX", + "laneCode": "A0504", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050504", + "zoneCode": "FLEX", + "laneCode": "A0504", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051104", + "zoneCode": "CACHE", + "laneCode": "B0504", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060304", + "zoneCode": "FLEX", + "laneCode": "A0604", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060404", + "zoneCode": "FLEX", + "laneCode": "A0604", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060504", + "zoneCode": "FLEX", + "laneCode": "A0604", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061104", + "zoneCode": "CACHE", + "laneCode": "B0604", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070104", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070204", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070304", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070404", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070504", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071104", + "zoneCode": "CACHE", + "laneCode": "B0704", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080104", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080204", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080304", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080404", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080504", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080704", + "zoneCode": "FLEX", + "laneCode": "C0804", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080804", + "zoneCode": "FLEX", + "laneCode": "C0804", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080904", + "zoneCode": "RESERVE", + "laneCode": "D0804", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081104", + "zoneCode": "CACHE", + "laneCode": "B0804", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090104", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090204", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090304", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090404", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090504", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090704", + "zoneCode": "FLEX", + "laneCode": "C0904", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090804", + "zoneCode": "FLEX", + "laneCode": "C0904", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090904", + "zoneCode": "RESERVE", + "laneCode": "D0904", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091104", + "zoneCode": "CACHE", + "laneCode": "B0904", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100104", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100204", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100304", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100404", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100504", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100704", + "zoneCode": "FLEX", + "laneCode": "C1004", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100804", + "zoneCode": "FLEX", + "laneCode": "C1004", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100904", + "zoneCode": "RESERVE", + "laneCode": "D1004", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101104", + "zoneCode": "CACHE", + "laneCode": "B1004", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110104", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110204", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110304", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110404", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110504", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110704", + "zoneCode": "FLEX", + "laneCode": "C1104", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110804", + "zoneCode": "FLEX", + "laneCode": "C1104", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110904", + "zoneCode": "RESERVE", + "laneCode": "D1104", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111104", + "zoneCode": "CACHE", + "laneCode": "B1104", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120104", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120204", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120304", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120404", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120504", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120704", + "zoneCode": "FLEX", + "laneCode": "C1204", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120804", + "zoneCode": "FLEX", + "laneCode": "C1204", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120904", + "zoneCode": "RESERVE", + "laneCode": "D1204", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121104", + "zoneCode": "CACHE", + "laneCode": "B1204", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130104", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130204", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130304", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130404", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130504", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130704", + "zoneCode": "FLEX", + "laneCode": "C1304", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130804", + "zoneCode": "FLEX", + "laneCode": "C1304", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130904", + "zoneCode": "FLEX", + "laneCode": "D1304", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131104", + "zoneCode": "RESERVE", + "laneCode": "B1304", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140104", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140204", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140304", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140404", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140504", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141104", + "zoneCode": "RESERVE", + "laneCode": "B1404", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020505", + "zoneCode": "FLEX", + "laneCode": "A0205", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030305", + "zoneCode": "FLEX", + "laneCode": "A0305", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030405", + "zoneCode": "FLEX", + "laneCode": "A0305", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030505", + "zoneCode": "FLEX", + "laneCode": "A0305", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031105", + "zoneCode": "CACHE", + "laneCode": "B0305", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040305", + "zoneCode": "FLEX", + "laneCode": "A0405", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040405", + "zoneCode": "FLEX", + "laneCode": "A0405", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040505", + "zoneCode": "FLEX", + "laneCode": "A0405", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041105", + "zoneCode": "CACHE", + "laneCode": "B0405", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050305", + "zoneCode": "FLEX", + "laneCode": "A0505", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050405", + "zoneCode": "FLEX", + "laneCode": "A0505", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050505", + "zoneCode": "FLEX", + "laneCode": "A0505", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051105", + "zoneCode": "CACHE", + "laneCode": "B0505", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060305", + "zoneCode": "FLEX", + "laneCode": "A0605", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060405", + "zoneCode": "FLEX", + "laneCode": "A0605", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060505", + "zoneCode": "FLEX", + "laneCode": "A0605", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061105", + "zoneCode": "CACHE", + "laneCode": "B0605", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070105", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070205", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070305", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070405", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070505", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071105", + "zoneCode": "CACHE", + "laneCode": "B0705", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080105", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080205", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080305", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080405", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080505", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080705", + "zoneCode": "FLEX", + "laneCode": "C0805", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080805", + "zoneCode": "FLEX", + "laneCode": "C0805", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080905", + "zoneCode": "RESERVE", + "laneCode": "D0805", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081105", + "zoneCode": "CACHE", + "laneCode": "B0805", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090105", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090205", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090305", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090405", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090505", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090705", + "zoneCode": "FLEX", + "laneCode": "C0905", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090805", + "zoneCode": "FLEX", + "laneCode": "C0905", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090905", + "zoneCode": "RESERVE", + "laneCode": "D0905", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091105", + "zoneCode": "CACHE", + "laneCode": "B0905", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100105", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100205", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100305", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100405", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100505", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100705", + "zoneCode": "FLEX", + "laneCode": "C1005", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100805", + "zoneCode": "FLEX", + "laneCode": "C1005", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100905", + "zoneCode": "RESERVE", + "laneCode": "D1005", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101105", + "zoneCode": "CACHE", + "laneCode": "B1005", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110105", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110205", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110305", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110405", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110505", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110705", + "zoneCode": "FLEX", + "laneCode": "C1105", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110805", + "zoneCode": "FLEX", + "laneCode": "C1105", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110905", + "zoneCode": "RESERVE", + "laneCode": "D1105", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111105", + "zoneCode": "CACHE", + "laneCode": "B1105", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120105", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120205", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120305", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120405", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120505", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120705", + "zoneCode": "FLEX", + "laneCode": "C1205", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120805", + "zoneCode": "FLEX", + "laneCode": "C1205", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120905", + "zoneCode": "RESERVE", + "laneCode": "D1205", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121105", + "zoneCode": "CACHE", + "laneCode": "B1205", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130105", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130205", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130305", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130405", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130505", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130705", + "zoneCode": "FLEX", + "laneCode": "C1305", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130805", + "zoneCode": "FLEX", + "laneCode": "C1305", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130905", + "zoneCode": "FLEX", + "laneCode": "D1305", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131105", + "zoneCode": "RESERVE", + "laneCode": "B1305", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140105", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140205", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140305", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140405", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140505", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141105", + "zoneCode": "RESERVE", + "laneCode": "B1405", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020506", + "zoneCode": "FLEX", + "laneCode": "A0206", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030306", + "zoneCode": "FLEX", + "laneCode": "A0306", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030406", + "zoneCode": "FLEX", + "laneCode": "A0306", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030506", + "zoneCode": "FLEX", + "laneCode": "A0306", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031106", + "zoneCode": "CACHE", + "laneCode": "B0306", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040306", + "zoneCode": "FLEX", + "laneCode": "A0406", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040406", + "zoneCode": "FLEX", + "laneCode": "A0406", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040506", + "zoneCode": "FLEX", + "laneCode": "A0406", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041106", + "zoneCode": "CACHE", + "laneCode": "B0406", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050306", + "zoneCode": "FLEX", + "laneCode": "A0506", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050406", + "zoneCode": "FLEX", + "laneCode": "A0506", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050506", + "zoneCode": "FLEX", + "laneCode": "A0506", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051106", + "zoneCode": "CACHE", + "laneCode": "B0506", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060306", + "zoneCode": "FLEX", + "laneCode": "A0606", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060406", + "zoneCode": "FLEX", + "laneCode": "A0606", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060506", + "zoneCode": "FLEX", + "laneCode": "A0606", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061106", + "zoneCode": "CACHE", + "laneCode": "B0606", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070106", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070206", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070306", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070406", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070506", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071106", + "zoneCode": "CACHE", + "laneCode": "B0706", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080106", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080206", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080306", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080406", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080506", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080706", + "zoneCode": "FLEX", + "laneCode": "C0806", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080806", + "zoneCode": "FLEX", + "laneCode": "C0806", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080906", + "zoneCode": "RESERVE", + "laneCode": "D0806", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081106", + "zoneCode": "CACHE", + "laneCode": "B0806", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090106", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090206", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090306", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090406", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090506", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090706", + "zoneCode": "FLEX", + "laneCode": "C0906", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090806", + "zoneCode": "FLEX", + "laneCode": "C0906", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090906", + "zoneCode": "RESERVE", + "laneCode": "D0906", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091106", + "zoneCode": "CACHE", + "laneCode": "B0906", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100106", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100206", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100306", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100406", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100506", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100706", + "zoneCode": "FLEX", + "laneCode": "C1006", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100806", + "zoneCode": "FLEX", + "laneCode": "C1006", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100906", + "zoneCode": "RESERVE", + "laneCode": "D1006", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101106", + "zoneCode": "CACHE", + "laneCode": "B1006", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110106", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110206", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110306", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110406", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110506", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110706", + "zoneCode": "FLEX", + "laneCode": "C1106", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110806", + "zoneCode": "FLEX", + "laneCode": "C1106", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110906", + "zoneCode": "RESERVE", + "laneCode": "D1106", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111106", + "zoneCode": "CACHE", + "laneCode": "B1106", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120106", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120206", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120306", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120406", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120506", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120706", + "zoneCode": "FLEX", + "laneCode": "C1206", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120806", + "zoneCode": "FLEX", + "laneCode": "C1206", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120906", + "zoneCode": "FLEX", + "laneCode": "D1206", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121106", + "zoneCode": "CACHE", + "laneCode": "B1206", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130106", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130206", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130306", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130406", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130506", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130706", + "zoneCode": "FLEX", + "laneCode": "C1306", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130806", + "zoneCode": "FLEX", + "laneCode": "C1306", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130906", + "zoneCode": "FLEX", + "laneCode": "D1306", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131106", + "zoneCode": "RESERVE", + "laneCode": "B1306", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140106", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140206", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140306", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140406", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140506", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141106", + "zoneCode": "RESERVE", + "laneCode": "B1406", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020507", + "zoneCode": "FLEX", + "laneCode": "A0207", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030307", + "zoneCode": "FLEX", + "laneCode": "A0307", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030407", + "zoneCode": "FLEX", + "laneCode": "A0307", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030507", + "zoneCode": "FLEX", + "laneCode": "A0307", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031107", + "zoneCode": "CACHE", + "laneCode": "B0307", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040307", + "zoneCode": "FLEX", + "laneCode": "A0407", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040407", + "zoneCode": "FLEX", + "laneCode": "A0407", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040507", + "zoneCode": "FLEX", + "laneCode": "A0407", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041107", + "zoneCode": "CACHE", + "laneCode": "B0407", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050307", + "zoneCode": "FLEX", + "laneCode": "A0507", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050407", + "zoneCode": "FLEX", + "laneCode": "A0507", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050507", + "zoneCode": "FLEX", + "laneCode": "A0507", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051107", + "zoneCode": "CACHE", + "laneCode": "B0507", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060307", + "zoneCode": "FLEX", + "laneCode": "A0607", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060407", + "zoneCode": "FLEX", + "laneCode": "A0607", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060507", + "zoneCode": "FLEX", + "laneCode": "A0607", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061107", + "zoneCode": "CACHE", + "laneCode": "B0607", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070107", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070207", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070307", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070407", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070507", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071107", + "zoneCode": "CACHE", + "laneCode": "B0707", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080107", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080207", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080307", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080407", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080507", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080707", + "zoneCode": "FLEX", + "laneCode": "C0807", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080807", + "zoneCode": "FLEX", + "laneCode": "C0807", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080907", + "zoneCode": "RESERVE", + "laneCode": "D0807", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081107", + "zoneCode": "CACHE", + "laneCode": "B0807", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090107", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090207", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090307", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090407", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090507", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090707", + "zoneCode": "FLEX", + "laneCode": "C0907", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090807", + "zoneCode": "FLEX", + "laneCode": "C0907", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090907", + "zoneCode": "RESERVE", + "laneCode": "D0907", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091107", + "zoneCode": "CACHE", + "laneCode": "B0907", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100107", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100207", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100307", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100407", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100507", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100707", + "zoneCode": "FLEX", + "laneCode": "C1007", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100807", + "zoneCode": "FLEX", + "laneCode": "C1007", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100907", + "zoneCode": "RESERVE", + "laneCode": "D1007", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101107", + "zoneCode": "CACHE", + "laneCode": "B1007", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110107", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110207", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110307", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110407", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110507", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110707", + "zoneCode": "FLEX", + "laneCode": "C1107", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110807", + "zoneCode": "FLEX", + "laneCode": "C1107", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110907", + "zoneCode": "RESERVE", + "laneCode": "D1107", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111107", + "zoneCode": "CACHE", + "laneCode": "B1107", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120107", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120207", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120307", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120407", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120507", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120707", + "zoneCode": "FLEX", + "laneCode": "C1207", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120807", + "zoneCode": "FLEX", + "laneCode": "C1207", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120907", + "zoneCode": "FLEX", + "laneCode": "D1207", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121107", + "zoneCode": "CACHE", + "laneCode": "B1207", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130107", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130207", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130307", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130407", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130507", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130707", + "zoneCode": "FLEX", + "laneCode": "C1307", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130807", + "zoneCode": "FLEX", + "laneCode": "C1307", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130907", + "zoneCode": "FLEX", + "laneCode": "D1307", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131107", + "zoneCode": "RESERVE", + "laneCode": "B1307", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140107", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140207", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140307", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140407", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140507", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141107", + "zoneCode": "RESERVE", + "laneCode": "B1407", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030308", + "zoneCode": "FLEX", + "laneCode": "A0308", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030408", + "zoneCode": "FLEX", + "laneCode": "A0308", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030508", + "zoneCode": "FLEX", + "laneCode": "A0308", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031108", + "zoneCode": "CACHE", + "laneCode": "B0308", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040308", + "zoneCode": "FLEX", + "laneCode": "A0408", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040408", + "zoneCode": "FLEX", + "laneCode": "A0408", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040508", + "zoneCode": "FLEX", + "laneCode": "A0408", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041108", + "zoneCode": "CACHE", + "laneCode": "B0408", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050308", + "zoneCode": "FLEX", + "laneCode": "A0508", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050408", + "zoneCode": "FLEX", + "laneCode": "A0508", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050508", + "zoneCode": "FLEX", + "laneCode": "A0508", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051108", + "zoneCode": "CACHE", + "laneCode": "B0508", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060308", + "zoneCode": "FLEX", + "laneCode": "A0608", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060408", + "zoneCode": "FLEX", + "laneCode": "A0608", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060508", + "zoneCode": "FLEX", + "laneCode": "A0608", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061108", + "zoneCode": "CACHE", + "laneCode": "B0608", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070108", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "OPEN-0", + "projectNo": "P-NEW", + "productId": "M-OLD", + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070208", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "OPEN-1", + "projectNo": "P-NEW", + "productId": "M-OLD", + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070308", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "OPEN-2", + "projectNo": "P-NEW", + "productId": "M-OLD", + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070408", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "OPEN-3", + "projectNo": "P-NEW", + "productId": "M-OLD", + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070508", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071108", + "zoneCode": "CACHE", + "laneCode": "B0708", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080108", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080208", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080308", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080408", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080508", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080708", + "zoneCode": "FLEX", + "laneCode": "C0808", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080808", + "zoneCode": "FLEX", + "laneCode": "C0808", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080908", + "zoneCode": "RESERVE", + "laneCode": "D0808", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081108", + "zoneCode": "CACHE", + "laneCode": "B0808", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090108", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090208", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090308", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090408", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090508", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090708", + "zoneCode": "FLEX", + "laneCode": "C0908", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090808", + "zoneCode": "FLEX", + "laneCode": "C0908", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090908", + "zoneCode": "RESERVE", + "laneCode": "D0908", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091108", + "zoneCode": "CACHE", + "laneCode": "B0908", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100108", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100208", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100308", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100408", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100508", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100708", + "zoneCode": "FLEX", + "laneCode": "C1008", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100808", + "zoneCode": "FLEX", + "laneCode": "C1008", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100908", + "zoneCode": "RESERVE", + "laneCode": "D1008", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101108", + "zoneCode": "CACHE", + "laneCode": "B1008", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110108", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110208", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110308", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110408", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110508", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110708", + "zoneCode": "FLEX", + "laneCode": "C1108", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110808", + "zoneCode": "FLEX", + "laneCode": "C1108", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110908", + "zoneCode": "RESERVE", + "laneCode": "D1108", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111108", + "zoneCode": "CACHE", + "laneCode": "B1108", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120108", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120208", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120308", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120408", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120508", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120708", + "zoneCode": "FLEX", + "laneCode": "C1208", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120808", + "zoneCode": "FLEX", + "laneCode": "C1208", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120908", + "zoneCode": "FLEX", + "laneCode": "D1208", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121108", + "zoneCode": "CACHE", + "laneCode": "B1208", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130108", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130208", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130308", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130408", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130508", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130708", + "zoneCode": "FLEX", + "laneCode": "C1308", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130808", + "zoneCode": "FLEX", + "laneCode": "C1308", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130908", + "zoneCode": "FLEX", + "laneCode": "D1308", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131108", + "zoneCode": "RESERVE", + "laneCode": "B1308", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140108", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140208", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140308", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140408", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140508", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141108", + "zoneCode": "RESERVE", + "laneCode": "B1408", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + } + ], + "expected": { + "planStatus": "READY", + "taskPlanCount": 1, + "plannedCount": 1, + "rejectedCount": 0, + "executionState": "READY_WITH_ELEVATOR_TOKEN", + "spaceId": "070508", + "laneCode": "A0708", + "ladderRung": "CONTINUE", + "capacityScore": 92.6, + "efficiencyScore": 13.1, + "totalScore": 84.7, + "openedNewLane": false + } + }, + { + "id": "efficiency-inbound", + "kind": "INBOUND", + "policy": { + "capacityWeight": 0.1, + "efficiencyWeight": 0.9 + }, + "request": { + "requestId": "IN-EFFICIENCY", + "trayNo": "TRAY-EFFICIENCY", + "projectNo": "P-NEW", + "productId": "M-NEW", + "lotNo": null, + "expectedProjectPallets": null, + "entryFloor": 1, + "targetFloor": null, + "batchLaneMode": "OPEN" + }, + "spaces": [ + { + "spaceId": "020501", + "zoneCode": "FLEX", + "laneCode": "A0201", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030301", + "zoneCode": "FLEX", + "laneCode": "A0301", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "OPEN-NEAR", + "projectNo": "P-NEW", + "productId": "M-OLD", + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030401", + "zoneCode": "FLEX", + "laneCode": "A0301", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030501", + "zoneCode": "FLEX", + "laneCode": "A0301", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031101", + "zoneCode": "CACHE", + "laneCode": "B0301", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040301", + "zoneCode": "FLEX", + "laneCode": "A0401", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040401", + "zoneCode": "FLEX", + "laneCode": "A0401", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040501", + "zoneCode": "FLEX", + "laneCode": "A0401", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041101", + "zoneCode": "CACHE", + "laneCode": "B0401", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050301", + "zoneCode": "FLEX", + "laneCode": "A0501", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050401", + "zoneCode": "FLEX", + "laneCode": "A0501", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050501", + "zoneCode": "FLEX", + "laneCode": "A0501", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051101", + "zoneCode": "CACHE", + "laneCode": "B0501", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060301", + "zoneCode": "FLEX", + "laneCode": "A0601", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060401", + "zoneCode": "FLEX", + "laneCode": "A0601", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060501", + "zoneCode": "FLEX", + "laneCode": "A0601", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061101", + "zoneCode": "CACHE", + "laneCode": "B0601", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070101", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070201", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070301", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070401", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070501", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071101", + "zoneCode": "CACHE", + "laneCode": "B0701", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080101", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080201", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080301", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080401", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080501", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080701", + "zoneCode": "FLEX", + "laneCode": "C0801", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080801", + "zoneCode": "FLEX", + "laneCode": "C0801", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080901", + "zoneCode": "RESERVE", + "laneCode": "D0801", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081101", + "zoneCode": "CACHE", + "laneCode": "B0801", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090101", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090201", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090301", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090401", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090501", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090701", + "zoneCode": "FLEX", + "laneCode": "C0901", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090801", + "zoneCode": "FLEX", + "laneCode": "C0901", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090901", + "zoneCode": "RESERVE", + "laneCode": "D0901", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091101", + "zoneCode": "CACHE", + "laneCode": "B0901", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100101", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100201", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100301", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100401", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100501", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100701", + "zoneCode": "FLEX", + "laneCode": "C1001", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100801", + "zoneCode": "FLEX", + "laneCode": "C1001", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100901", + "zoneCode": "RESERVE", + "laneCode": "D1001", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101101", + "zoneCode": "CACHE", + "laneCode": "B1001", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110101", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110201", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110301", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110401", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110501", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110701", + "zoneCode": "FLEX", + "laneCode": "C1101", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110801", + "zoneCode": "FLEX", + "laneCode": "C1101", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110901", + "zoneCode": "RESERVE", + "laneCode": "D1101", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111101", + "zoneCode": "CACHE", + "laneCode": "B1101", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120101", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120201", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120301", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120401", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120501", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120701", + "zoneCode": "FLEX", + "laneCode": "C1201", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120801", + "zoneCode": "FLEX", + "laneCode": "C1201", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120901", + "zoneCode": "RESERVE", + "laneCode": "D1201", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121101", + "zoneCode": "CACHE", + "laneCode": "B1201", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130101", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130201", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130301", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130401", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130501", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130701", + "zoneCode": "FLEX", + "laneCode": "C1301", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130801", + "zoneCode": "FLEX", + "laneCode": "C1301", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130901", + "zoneCode": "FLEX", + "laneCode": "D1301", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131101", + "zoneCode": "RESERVE", + "laneCode": "B1301", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140101", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140201", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140301", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140401", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140501", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141101", + "zoneCode": "RESERVE", + "laneCode": "B1401", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020502", + "zoneCode": "FLEX", + "laneCode": "A0202", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030302", + "zoneCode": "FLEX", + "laneCode": "A0302", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030402", + "zoneCode": "FLEX", + "laneCode": "A0302", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030502", + "zoneCode": "FLEX", + "laneCode": "A0302", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031102", + "zoneCode": "CACHE", + "laneCode": "B0302", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040302", + "zoneCode": "FLEX", + "laneCode": "A0402", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040402", + "zoneCode": "FLEX", + "laneCode": "A0402", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040502", + "zoneCode": "FLEX", + "laneCode": "A0402", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041102", + "zoneCode": "CACHE", + "laneCode": "B0402", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050302", + "zoneCode": "FLEX", + "laneCode": "A0502", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050402", + "zoneCode": "FLEX", + "laneCode": "A0502", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050502", + "zoneCode": "FLEX", + "laneCode": "A0502", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051102", + "zoneCode": "CACHE", + "laneCode": "B0502", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060302", + "zoneCode": "FLEX", + "laneCode": "A0602", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060402", + "zoneCode": "FLEX", + "laneCode": "A0602", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060502", + "zoneCode": "FLEX", + "laneCode": "A0602", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061102", + "zoneCode": "CACHE", + "laneCode": "B0602", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070102", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070202", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070302", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070402", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070502", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071102", + "zoneCode": "CACHE", + "laneCode": "B0702", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080102", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080202", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080302", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080402", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080502", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080702", + "zoneCode": "FLEX", + "laneCode": "C0802", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080802", + "zoneCode": "FLEX", + "laneCode": "C0802", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080902", + "zoneCode": "RESERVE", + "laneCode": "D0802", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081102", + "zoneCode": "CACHE", + "laneCode": "B0802", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090102", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090202", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090302", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090402", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090502", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090702", + "zoneCode": "FLEX", + "laneCode": "C0902", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090802", + "zoneCode": "FLEX", + "laneCode": "C0902", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090902", + "zoneCode": "RESERVE", + "laneCode": "D0902", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091102", + "zoneCode": "CACHE", + "laneCode": "B0902", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100102", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100202", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100302", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100402", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100502", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100702", + "zoneCode": "FLEX", + "laneCode": "C1002", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100802", + "zoneCode": "FLEX", + "laneCode": "C1002", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100902", + "zoneCode": "RESERVE", + "laneCode": "D1002", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101102", + "zoneCode": "CACHE", + "laneCode": "B1002", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110102", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110202", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110302", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110402", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110502", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110702", + "zoneCode": "FLEX", + "laneCode": "C1102", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110802", + "zoneCode": "FLEX", + "laneCode": "C1102", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110902", + "zoneCode": "RESERVE", + "laneCode": "D1102", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111102", + "zoneCode": "CACHE", + "laneCode": "B1102", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120102", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120202", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120302", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120402", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120502", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120702", + "zoneCode": "FLEX", + "laneCode": "C1202", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120802", + "zoneCode": "FLEX", + "laneCode": "C1202", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120902", + "zoneCode": "RESERVE", + "laneCode": "D1202", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121102", + "zoneCode": "CACHE", + "laneCode": "B1202", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130102", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130202", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130302", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130402", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130502", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130702", + "zoneCode": "FLEX", + "laneCode": "C1302", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130802", + "zoneCode": "FLEX", + "laneCode": "C1302", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130902", + "zoneCode": "FLEX", + "laneCode": "D1302", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131102", + "zoneCode": "RESERVE", + "laneCode": "B1302", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140102", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140202", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140302", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140402", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140502", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141102", + "zoneCode": "RESERVE", + "laneCode": "B1402", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020503", + "zoneCode": "FLEX", + "laneCode": "A0203", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030303", + "zoneCode": "FLEX", + "laneCode": "A0303", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030403", + "zoneCode": "FLEX", + "laneCode": "A0303", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030503", + "zoneCode": "FLEX", + "laneCode": "A0303", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031103", + "zoneCode": "CACHE", + "laneCode": "B0303", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040303", + "zoneCode": "FLEX", + "laneCode": "A0403", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040403", + "zoneCode": "FLEX", + "laneCode": "A0403", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040503", + "zoneCode": "FLEX", + "laneCode": "A0403", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041103", + "zoneCode": "CACHE", + "laneCode": "B0403", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050303", + "zoneCode": "FLEX", + "laneCode": "A0503", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050403", + "zoneCode": "FLEX", + "laneCode": "A0503", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050503", + "zoneCode": "FLEX", + "laneCode": "A0503", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051103", + "zoneCode": "CACHE", + "laneCode": "B0503", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060303", + "zoneCode": "FLEX", + "laneCode": "A0603", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060403", + "zoneCode": "FLEX", + "laneCode": "A0603", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060503", + "zoneCode": "FLEX", + "laneCode": "A0603", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061103", + "zoneCode": "CACHE", + "laneCode": "B0603", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070103", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070203", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070303", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070403", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070503", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071103", + "zoneCode": "CACHE", + "laneCode": "B0703", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080103", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080203", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080303", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080403", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080503", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080703", + "zoneCode": "FLEX", + "laneCode": "C0803", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080803", + "zoneCode": "FLEX", + "laneCode": "C0803", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080903", + "zoneCode": "RESERVE", + "laneCode": "D0803", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081103", + "zoneCode": "CACHE", + "laneCode": "B0803", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090103", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090203", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090303", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090403", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090503", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090703", + "zoneCode": "FLEX", + "laneCode": "C0903", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090803", + "zoneCode": "FLEX", + "laneCode": "C0903", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090903", + "zoneCode": "RESERVE", + "laneCode": "D0903", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091103", + "zoneCode": "CACHE", + "laneCode": "B0903", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100103", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100203", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100303", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100403", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100503", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100703", + "zoneCode": "FLEX", + "laneCode": "C1003", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100803", + "zoneCode": "FLEX", + "laneCode": "C1003", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100903", + "zoneCode": "RESERVE", + "laneCode": "D1003", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101103", + "zoneCode": "CACHE", + "laneCode": "B1003", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110103", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110203", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110303", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110403", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110503", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110703", + "zoneCode": "FLEX", + "laneCode": "C1103", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110803", + "zoneCode": "FLEX", + "laneCode": "C1103", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110903", + "zoneCode": "RESERVE", + "laneCode": "D1103", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111103", + "zoneCode": "CACHE", + "laneCode": "B1103", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120103", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120203", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120303", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120403", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120503", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120703", + "zoneCode": "FLEX", + "laneCode": "C1203", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120803", + "zoneCode": "FLEX", + "laneCode": "C1203", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120903", + "zoneCode": "RESERVE", + "laneCode": "D1203", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121103", + "zoneCode": "CACHE", + "laneCode": "B1203", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130103", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130203", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130303", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130403", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130503", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130703", + "zoneCode": "FLEX", + "laneCode": "C1303", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130803", + "zoneCode": "FLEX", + "laneCode": "C1303", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130903", + "zoneCode": "FLEX", + "laneCode": "D1303", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131103", + "zoneCode": "RESERVE", + "laneCode": "B1303", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140103", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140203", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140303", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140403", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140503", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141103", + "zoneCode": "RESERVE", + "laneCode": "B1403", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020504", + "zoneCode": "FLEX", + "laneCode": "A0204", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030304", + "zoneCode": "FLEX", + "laneCode": "A0304", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030404", + "zoneCode": "FLEX", + "laneCode": "A0304", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030504", + "zoneCode": "FLEX", + "laneCode": "A0304", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031104", + "zoneCode": "CACHE", + "laneCode": "B0304", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040304", + "zoneCode": "FLEX", + "laneCode": "A0404", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040404", + "zoneCode": "FLEX", + "laneCode": "A0404", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040504", + "zoneCode": "FLEX", + "laneCode": "A0404", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041104", + "zoneCode": "CACHE", + "laneCode": "B0404", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050304", + "zoneCode": "FLEX", + "laneCode": "A0504", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050404", + "zoneCode": "FLEX", + "laneCode": "A0504", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050504", + "zoneCode": "FLEX", + "laneCode": "A0504", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051104", + "zoneCode": "CACHE", + "laneCode": "B0504", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060304", + "zoneCode": "FLEX", + "laneCode": "A0604", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060404", + "zoneCode": "FLEX", + "laneCode": "A0604", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060504", + "zoneCode": "FLEX", + "laneCode": "A0604", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061104", + "zoneCode": "CACHE", + "laneCode": "B0604", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070104", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070204", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070304", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070404", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070504", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071104", + "zoneCode": "CACHE", + "laneCode": "B0704", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080104", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080204", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080304", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080404", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080504", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080704", + "zoneCode": "FLEX", + "laneCode": "C0804", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080804", + "zoneCode": "FLEX", + "laneCode": "C0804", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080904", + "zoneCode": "RESERVE", + "laneCode": "D0804", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081104", + "zoneCode": "CACHE", + "laneCode": "B0804", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090104", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090204", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090304", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090404", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090504", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090704", + "zoneCode": "FLEX", + "laneCode": "C0904", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090804", + "zoneCode": "FLEX", + "laneCode": "C0904", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090904", + "zoneCode": "RESERVE", + "laneCode": "D0904", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091104", + "zoneCode": "CACHE", + "laneCode": "B0904", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100104", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100204", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100304", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100404", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100504", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100704", + "zoneCode": "FLEX", + "laneCode": "C1004", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100804", + "zoneCode": "FLEX", + "laneCode": "C1004", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100904", + "zoneCode": "RESERVE", + "laneCode": "D1004", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101104", + "zoneCode": "CACHE", + "laneCode": "B1004", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110104", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110204", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110304", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110404", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110504", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110704", + "zoneCode": "FLEX", + "laneCode": "C1104", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110804", + "zoneCode": "FLEX", + "laneCode": "C1104", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110904", + "zoneCode": "RESERVE", + "laneCode": "D1104", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111104", + "zoneCode": "CACHE", + "laneCode": "B1104", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120104", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120204", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120304", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120404", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120504", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120704", + "zoneCode": "FLEX", + "laneCode": "C1204", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120804", + "zoneCode": "FLEX", + "laneCode": "C1204", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120904", + "zoneCode": "RESERVE", + "laneCode": "D1204", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121104", + "zoneCode": "CACHE", + "laneCode": "B1204", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130104", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130204", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130304", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130404", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130504", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130704", + "zoneCode": "FLEX", + "laneCode": "C1304", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130804", + "zoneCode": "FLEX", + "laneCode": "C1304", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130904", + "zoneCode": "FLEX", + "laneCode": "D1304", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131104", + "zoneCode": "RESERVE", + "laneCode": "B1304", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140104", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140204", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140304", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140404", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140504", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141104", + "zoneCode": "RESERVE", + "laneCode": "B1404", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020505", + "zoneCode": "FLEX", + "laneCode": "A0205", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030305", + "zoneCode": "FLEX", + "laneCode": "A0305", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030405", + "zoneCode": "FLEX", + "laneCode": "A0305", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030505", + "zoneCode": "FLEX", + "laneCode": "A0305", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031105", + "zoneCode": "CACHE", + "laneCode": "B0305", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040305", + "zoneCode": "FLEX", + "laneCode": "A0405", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040405", + "zoneCode": "FLEX", + "laneCode": "A0405", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040505", + "zoneCode": "FLEX", + "laneCode": "A0405", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041105", + "zoneCode": "CACHE", + "laneCode": "B0405", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050305", + "zoneCode": "FLEX", + "laneCode": "A0505", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050405", + "zoneCode": "FLEX", + "laneCode": "A0505", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050505", + "zoneCode": "FLEX", + "laneCode": "A0505", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051105", + "zoneCode": "CACHE", + "laneCode": "B0505", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060305", + "zoneCode": "FLEX", + "laneCode": "A0605", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060405", + "zoneCode": "FLEX", + "laneCode": "A0605", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060505", + "zoneCode": "FLEX", + "laneCode": "A0605", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061105", + "zoneCode": "CACHE", + "laneCode": "B0605", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070105", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070205", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070305", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070405", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070505", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071105", + "zoneCode": "CACHE", + "laneCode": "B0705", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080105", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080205", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080305", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080405", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080505", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080705", + "zoneCode": "FLEX", + "laneCode": "C0805", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080805", + "zoneCode": "FLEX", + "laneCode": "C0805", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080905", + "zoneCode": "RESERVE", + "laneCode": "D0805", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081105", + "zoneCode": "CACHE", + "laneCode": "B0805", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090105", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090205", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090305", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090405", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090505", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090705", + "zoneCode": "FLEX", + "laneCode": "C0905", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090805", + "zoneCode": "FLEX", + "laneCode": "C0905", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090905", + "zoneCode": "RESERVE", + "laneCode": "D0905", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091105", + "zoneCode": "CACHE", + "laneCode": "B0905", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100105", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100205", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100305", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100405", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100505", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100705", + "zoneCode": "FLEX", + "laneCode": "C1005", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100805", + "zoneCode": "FLEX", + "laneCode": "C1005", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100905", + "zoneCode": "RESERVE", + "laneCode": "D1005", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101105", + "zoneCode": "CACHE", + "laneCode": "B1005", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110105", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110205", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110305", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110405", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110505", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110705", + "zoneCode": "FLEX", + "laneCode": "C1105", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110805", + "zoneCode": "FLEX", + "laneCode": "C1105", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110905", + "zoneCode": "RESERVE", + "laneCode": "D1105", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111105", + "zoneCode": "CACHE", + "laneCode": "B1105", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120105", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120205", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120305", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120405", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120505", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120705", + "zoneCode": "FLEX", + "laneCode": "C1205", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120805", + "zoneCode": "FLEX", + "laneCode": "C1205", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120905", + "zoneCode": "RESERVE", + "laneCode": "D1205", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121105", + "zoneCode": "CACHE", + "laneCode": "B1205", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130105", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130205", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130305", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130405", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130505", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130705", + "zoneCode": "FLEX", + "laneCode": "C1305", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130805", + "zoneCode": "FLEX", + "laneCode": "C1305", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130905", + "zoneCode": "FLEX", + "laneCode": "D1305", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131105", + "zoneCode": "RESERVE", + "laneCode": "B1305", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140105", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140205", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140305", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140405", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140505", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141105", + "zoneCode": "RESERVE", + "laneCode": "B1405", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020506", + "zoneCode": "FLEX", + "laneCode": "A0206", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030306", + "zoneCode": "FLEX", + "laneCode": "A0306", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030406", + "zoneCode": "FLEX", + "laneCode": "A0306", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030506", + "zoneCode": "FLEX", + "laneCode": "A0306", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031106", + "zoneCode": "CACHE", + "laneCode": "B0306", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040306", + "zoneCode": "FLEX", + "laneCode": "A0406", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040406", + "zoneCode": "FLEX", + "laneCode": "A0406", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040506", + "zoneCode": "FLEX", + "laneCode": "A0406", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041106", + "zoneCode": "CACHE", + "laneCode": "B0406", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050306", + "zoneCode": "FLEX", + "laneCode": "A0506", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050406", + "zoneCode": "FLEX", + "laneCode": "A0506", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050506", + "zoneCode": "FLEX", + "laneCode": "A0506", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051106", + "zoneCode": "CACHE", + "laneCode": "B0506", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060306", + "zoneCode": "FLEX", + "laneCode": "A0606", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060406", + "zoneCode": "FLEX", + "laneCode": "A0606", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060506", + "zoneCode": "FLEX", + "laneCode": "A0606", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061106", + "zoneCode": "CACHE", + "laneCode": "B0606", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070106", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070206", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070306", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070406", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070506", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071106", + "zoneCode": "CACHE", + "laneCode": "B0706", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080106", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080206", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080306", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080406", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080506", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080706", + "zoneCode": "FLEX", + "laneCode": "C0806", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080806", + "zoneCode": "FLEX", + "laneCode": "C0806", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080906", + "zoneCode": "RESERVE", + "laneCode": "D0806", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081106", + "zoneCode": "CACHE", + "laneCode": "B0806", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090106", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090206", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090306", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090406", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090506", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090706", + "zoneCode": "FLEX", + "laneCode": "C0906", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090806", + "zoneCode": "FLEX", + "laneCode": "C0906", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090906", + "zoneCode": "RESERVE", + "laneCode": "D0906", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091106", + "zoneCode": "CACHE", + "laneCode": "B0906", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100106", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100206", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100306", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100406", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100506", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100706", + "zoneCode": "FLEX", + "laneCode": "C1006", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100806", + "zoneCode": "FLEX", + "laneCode": "C1006", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100906", + "zoneCode": "RESERVE", + "laneCode": "D1006", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101106", + "zoneCode": "CACHE", + "laneCode": "B1006", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110106", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110206", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110306", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110406", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110506", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110706", + "zoneCode": "FLEX", + "laneCode": "C1106", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110806", + "zoneCode": "FLEX", + "laneCode": "C1106", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110906", + "zoneCode": "RESERVE", + "laneCode": "D1106", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111106", + "zoneCode": "CACHE", + "laneCode": "B1106", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120106", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120206", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120306", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120406", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120506", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120706", + "zoneCode": "FLEX", + "laneCode": "C1206", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120806", + "zoneCode": "FLEX", + "laneCode": "C1206", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120906", + "zoneCode": "FLEX", + "laneCode": "D1206", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121106", + "zoneCode": "CACHE", + "laneCode": "B1206", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130106", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130206", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130306", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130406", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130506", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130706", + "zoneCode": "FLEX", + "laneCode": "C1306", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130806", + "zoneCode": "FLEX", + "laneCode": "C1306", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130906", + "zoneCode": "FLEX", + "laneCode": "D1306", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131106", + "zoneCode": "RESERVE", + "laneCode": "B1306", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140106", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140206", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140306", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140406", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140506", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141106", + "zoneCode": "RESERVE", + "laneCode": "B1406", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020507", + "zoneCode": "FLEX", + "laneCode": "A0207", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030307", + "zoneCode": "FLEX", + "laneCode": "A0307", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030407", + "zoneCode": "FLEX", + "laneCode": "A0307", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030507", + "zoneCode": "FLEX", + "laneCode": "A0307", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031107", + "zoneCode": "CACHE", + "laneCode": "B0307", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040307", + "zoneCode": "FLEX", + "laneCode": "A0407", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040407", + "zoneCode": "FLEX", + "laneCode": "A0407", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040507", + "zoneCode": "FLEX", + "laneCode": "A0407", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041107", + "zoneCode": "CACHE", + "laneCode": "B0407", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050307", + "zoneCode": "FLEX", + "laneCode": "A0507", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050407", + "zoneCode": "FLEX", + "laneCode": "A0507", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050507", + "zoneCode": "FLEX", + "laneCode": "A0507", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051107", + "zoneCode": "CACHE", + "laneCode": "B0507", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060307", + "zoneCode": "FLEX", + "laneCode": "A0607", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060407", + "zoneCode": "FLEX", + "laneCode": "A0607", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060507", + "zoneCode": "FLEX", + "laneCode": "A0607", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061107", + "zoneCode": "CACHE", + "laneCode": "B0607", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070107", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070207", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070307", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070407", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070507", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071107", + "zoneCode": "CACHE", + "laneCode": "B0707", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080107", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080207", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080307", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080407", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080507", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080707", + "zoneCode": "FLEX", + "laneCode": "C0807", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080807", + "zoneCode": "FLEX", + "laneCode": "C0807", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080907", + "zoneCode": "RESERVE", + "laneCode": "D0807", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081107", + "zoneCode": "CACHE", + "laneCode": "B0807", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090107", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090207", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090307", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090407", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090507", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090707", + "zoneCode": "FLEX", + "laneCode": "C0907", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090807", + "zoneCode": "FLEX", + "laneCode": "C0907", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090907", + "zoneCode": "RESERVE", + "laneCode": "D0907", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091107", + "zoneCode": "CACHE", + "laneCode": "B0907", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100107", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100207", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100307", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100407", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100507", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100707", + "zoneCode": "FLEX", + "laneCode": "C1007", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100807", + "zoneCode": "FLEX", + "laneCode": "C1007", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100907", + "zoneCode": "RESERVE", + "laneCode": "D1007", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101107", + "zoneCode": "CACHE", + "laneCode": "B1007", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110107", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110207", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110307", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110407", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110507", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110707", + "zoneCode": "FLEX", + "laneCode": "C1107", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110807", + "zoneCode": "FLEX", + "laneCode": "C1107", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110907", + "zoneCode": "RESERVE", + "laneCode": "D1107", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111107", + "zoneCode": "CACHE", + "laneCode": "B1107", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120107", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120207", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120307", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120407", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120507", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120707", + "zoneCode": "FLEX", + "laneCode": "C1207", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120807", + "zoneCode": "FLEX", + "laneCode": "C1207", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120907", + "zoneCode": "FLEX", + "laneCode": "D1207", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121107", + "zoneCode": "CACHE", + "laneCode": "B1207", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130107", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130207", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130307", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130407", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130507", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130707", + "zoneCode": "FLEX", + "laneCode": "C1307", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130807", + "zoneCode": "FLEX", + "laneCode": "C1307", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130907", + "zoneCode": "FLEX", + "laneCode": "D1307", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131107", + "zoneCode": "RESERVE", + "laneCode": "B1307", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140107", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140207", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140307", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140407", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140507", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141107", + "zoneCode": "RESERVE", + "laneCode": "B1407", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030308", + "zoneCode": "FLEX", + "laneCode": "A0308", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030408", + "zoneCode": "FLEX", + "laneCode": "A0308", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030508", + "zoneCode": "FLEX", + "laneCode": "A0308", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031108", + "zoneCode": "CACHE", + "laneCode": "B0308", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040308", + "zoneCode": "FLEX", + "laneCode": "A0408", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040408", + "zoneCode": "FLEX", + "laneCode": "A0408", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040508", + "zoneCode": "FLEX", + "laneCode": "A0408", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041108", + "zoneCode": "CACHE", + "laneCode": "B0408", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050308", + "zoneCode": "FLEX", + "laneCode": "A0508", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050408", + "zoneCode": "FLEX", + "laneCode": "A0508", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050508", + "zoneCode": "FLEX", + "laneCode": "A0508", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051108", + "zoneCode": "CACHE", + "laneCode": "B0508", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060308", + "zoneCode": "FLEX", + "laneCode": "A0608", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060408", + "zoneCode": "FLEX", + "laneCode": "A0608", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060508", + "zoneCode": "FLEX", + "laneCode": "A0608", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061108", + "zoneCode": "CACHE", + "laneCode": "B0608", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070108", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "OPEN-0", + "projectNo": "P-NEW", + "productId": "M-OLD", + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070208", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "OPEN-1", + "projectNo": "P-NEW", + "productId": "M-OLD", + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070308", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "OPEN-2", + "projectNo": "P-NEW", + "productId": "M-OLD", + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070408", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "OPEN-3", + "projectNo": "P-NEW", + "productId": "M-OLD", + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070508", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071108", + "zoneCode": "CACHE", + "laneCode": "B0708", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080108", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080208", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080308", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080408", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080508", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080708", + "zoneCode": "FLEX", + "laneCode": "C0808", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080808", + "zoneCode": "FLEX", + "laneCode": "C0808", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080908", + "zoneCode": "RESERVE", + "laneCode": "D0808", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081108", + "zoneCode": "CACHE", + "laneCode": "B0808", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090108", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090208", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090308", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090408", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090508", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090708", + "zoneCode": "FLEX", + "laneCode": "C0908", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090808", + "zoneCode": "FLEX", + "laneCode": "C0908", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090908", + "zoneCode": "RESERVE", + "laneCode": "D0908", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091108", + "zoneCode": "CACHE", + "laneCode": "B0908", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100108", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100208", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100308", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100408", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100508", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100708", + "zoneCode": "FLEX", + "laneCode": "C1008", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100808", + "zoneCode": "FLEX", + "laneCode": "C1008", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100908", + "zoneCode": "RESERVE", + "laneCode": "D1008", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101108", + "zoneCode": "CACHE", + "laneCode": "B1008", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110108", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110208", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110308", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110408", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110508", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110708", + "zoneCode": "FLEX", + "laneCode": "C1108", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110808", + "zoneCode": "FLEX", + "laneCode": "C1108", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110908", + "zoneCode": "RESERVE", + "laneCode": "D1108", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111108", + "zoneCode": "CACHE", + "laneCode": "B1108", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120108", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120208", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120308", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120408", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120508", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120708", + "zoneCode": "FLEX", + "laneCode": "C1208", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120808", + "zoneCode": "FLEX", + "laneCode": "C1208", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120908", + "zoneCode": "FLEX", + "laneCode": "D1208", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121108", + "zoneCode": "CACHE", + "laneCode": "B1208", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130108", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130208", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130308", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130408", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130508", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130708", + "zoneCode": "FLEX", + "laneCode": "C1308", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130808", + "zoneCode": "FLEX", + "laneCode": "C1308", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130908", + "zoneCode": "FLEX", + "laneCode": "D1308", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131108", + "zoneCode": "RESERVE", + "laneCode": "B1308", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140108", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140208", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140308", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140408", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140508", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141108", + "zoneCode": "RESERVE", + "laneCode": "B1408", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + } + ], + "expected": { + "planStatus": "READY", + "taskPlanCount": 1, + "plannedCount": 1, + "rejectedCount": 0, + "executionState": "READY", + "spaceId": "030401", + "laneCode": "A0301", + "ladderRung": "CONTINUE", + "capacityScore": 72.3, + "efficiencyScore": 96.9, + "totalScore": 94.4, + "openedNewLane": false + } + }, + { + "id": "fifo-strict-outbound", + "kind": "OUTBOUND", + "policy": { + "capacityWeight": 0.5, + "efficiencyWeight": 0.5 + }, + "request": { + "requestId": "OUT-FIFO-STRICT", + "trayNo": null, + "projectNo": "P-FIFO-DEMO", + "productId": "M-FIFO-DEMO", + "fifoMode": "STRICT", + "fifoToleranceMinutes": 0, + "exitFloor": 1 + }, + "spaces": [ + { + "spaceId": "020501", + "zoneCode": "FLEX", + "laneCode": "A0201", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030301", + "zoneCode": "FLEX", + "laneCode": "A0301", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030401", + "zoneCode": "FLEX", + "laneCode": "A0301", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030501", + "zoneCode": "FLEX", + "laneCode": "A0301", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031101", + "zoneCode": "CACHE", + "laneCode": "B0301", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040301", + "zoneCode": "FLEX", + "laneCode": "A0401", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040401", + "zoneCode": "FLEX", + "laneCode": "A0401", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040501", + "zoneCode": "FLEX", + "laneCode": "A0401", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041101", + "zoneCode": "CACHE", + "laneCode": "B0401", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050301", + "zoneCode": "FLEX", + "laneCode": "A0501", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050401", + "zoneCode": "FLEX", + "laneCode": "A0501", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050501", + "zoneCode": "FLEX", + "laneCode": "A0501", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051101", + "zoneCode": "CACHE", + "laneCode": "B0501", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060301", + "zoneCode": "FLEX", + "laneCode": "A0601", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060401", + "zoneCode": "FLEX", + "laneCode": "A0601", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060501", + "zoneCode": "FLEX", + "laneCode": "A0601", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061101", + "zoneCode": "CACHE", + "laneCode": "B0601", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070101", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070201", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070301", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070401", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070501", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071101", + "zoneCode": "CACHE", + "laneCode": "B0701", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080101", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-DIRECT-INNER-1", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-02", + "inboundAt": "2026-07-01T12:00:00+08:00" + }, + { + "spaceId": "080201", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-DIRECT-INNER-2", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-02", + "inboundAt": "2026-07-01T12:00:00+08:00" + }, + { + "spaceId": "080301", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-DIRECT-INNER-3", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-02", + "inboundAt": "2026-07-01T12:00:00+08:00" + }, + { + "spaceId": "080401", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-DIRECT-INNER-4", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-02", + "inboundAt": "2026-07-01T12:00:00+08:00" + }, + { + "spaceId": "080501", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-DIRECT", + "projectNo": "P-FIFO-DEMO", + "productId": "M-FIFO-DEMO", + "lotNo": "FIFO-LOT-02", + "inboundAt": "2026-07-01T20:00:00+08:00" + }, + { + "spaceId": "080701", + "zoneCode": "FLEX", + "laneCode": "C0801", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080801", + "zoneCode": "FLEX", + "laneCode": "C0801", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080901", + "zoneCode": "RESERVE", + "laneCode": "D0801", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081101", + "zoneCode": "CACHE", + "laneCode": "B0801", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090101", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090201", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090301", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090401", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090501", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090701", + "zoneCode": "FLEX", + "laneCode": "C0901", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090801", + "zoneCode": "FLEX", + "laneCode": "C0901", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090901", + "zoneCode": "RESERVE", + "laneCode": "D0901", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091101", + "zoneCode": "CACHE", + "laneCode": "B0901", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100101", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100201", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100301", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100401", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100501", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100701", + "zoneCode": "FLEX", + "laneCode": "C1001", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100801", + "zoneCode": "FLEX", + "laneCode": "C1001", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100901", + "zoneCode": "RESERVE", + "laneCode": "D1001", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101101", + "zoneCode": "CACHE", + "laneCode": "B1001", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110101", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110201", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110301", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110401", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110501", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110701", + "zoneCode": "FLEX", + "laneCode": "C1101", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110801", + "zoneCode": "FLEX", + "laneCode": "C1101", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110901", + "zoneCode": "RESERVE", + "laneCode": "D1101", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111101", + "zoneCode": "CACHE", + "laneCode": "B1101", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120101", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120201", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120301", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120401", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120501", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120701", + "zoneCode": "FLEX", + "laneCode": "C1201", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120801", + "zoneCode": "FLEX", + "laneCode": "C1201", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120901", + "zoneCode": "RESERVE", + "laneCode": "D1201", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121101", + "zoneCode": "CACHE", + "laneCode": "B1201", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130101", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130201", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130301", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130401", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130501", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130701", + "zoneCode": "FLEX", + "laneCode": "C1301", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130801", + "zoneCode": "FLEX", + "laneCode": "C1301", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130901", + "zoneCode": "FLEX", + "laneCode": "D1301", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131101", + "zoneCode": "RESERVE", + "laneCode": "B1301", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140101", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140201", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140301", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140401", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140501", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141101", + "zoneCode": "RESERVE", + "laneCode": "B1401", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020502", + "zoneCode": "FLEX", + "laneCode": "A0202", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030302", + "zoneCode": "FLEX", + "laneCode": "A0302", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030402", + "zoneCode": "FLEX", + "laneCode": "A0302", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030502", + "zoneCode": "FLEX", + "laneCode": "A0302", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031102", + "zoneCode": "CACHE", + "laneCode": "B0302", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040302", + "zoneCode": "FLEX", + "laneCode": "A0402", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040402", + "zoneCode": "FLEX", + "laneCode": "A0402", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040502", + "zoneCode": "FLEX", + "laneCode": "A0402", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041102", + "zoneCode": "CACHE", + "laneCode": "B0402", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050302", + "zoneCode": "FLEX", + "laneCode": "A0502", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050402", + "zoneCode": "FLEX", + "laneCode": "A0502", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050502", + "zoneCode": "FLEX", + "laneCode": "A0502", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051102", + "zoneCode": "CACHE", + "laneCode": "B0502", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060302", + "zoneCode": "FLEX", + "laneCode": "A0602", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060402", + "zoneCode": "FLEX", + "laneCode": "A0602", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060502", + "zoneCode": "FLEX", + "laneCode": "A0602", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061102", + "zoneCode": "CACHE", + "laneCode": "B0602", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070102", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070202", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070302", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070402", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070502", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071102", + "zoneCode": "CACHE", + "laneCode": "B0702", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080102", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080202", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080302", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080402", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080502", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080702", + "zoneCode": "FLEX", + "laneCode": "C0802", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080802", + "zoneCode": "FLEX", + "laneCode": "C0802", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080902", + "zoneCode": "RESERVE", + "laneCode": "D0802", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081102", + "zoneCode": "CACHE", + "laneCode": "B0802", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090102", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090202", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090302", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090402", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090502", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090702", + "zoneCode": "FLEX", + "laneCode": "C0902", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090802", + "zoneCode": "FLEX", + "laneCode": "C0902", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090902", + "zoneCode": "RESERVE", + "laneCode": "D0902", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091102", + "zoneCode": "CACHE", + "laneCode": "B0902", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100102", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100202", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100302", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100402", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100502", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100702", + "zoneCode": "FLEX", + "laneCode": "C1002", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100802", + "zoneCode": "FLEX", + "laneCode": "C1002", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100902", + "zoneCode": "RESERVE", + "laneCode": "D1002", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101102", + "zoneCode": "CACHE", + "laneCode": "B1002", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110102", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110202", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110302", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110402", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110502", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110702", + "zoneCode": "FLEX", + "laneCode": "C1102", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110802", + "zoneCode": "FLEX", + "laneCode": "C1102", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110902", + "zoneCode": "RESERVE", + "laneCode": "D1102", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111102", + "zoneCode": "CACHE", + "laneCode": "B1102", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120102", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120202", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120302", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120402", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120502", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120702", + "zoneCode": "FLEX", + "laneCode": "C1202", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120802", + "zoneCode": "FLEX", + "laneCode": "C1202", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120902", + "zoneCode": "RESERVE", + "laneCode": "D1202", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121102", + "zoneCode": "CACHE", + "laneCode": "B1202", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130102", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130202", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130302", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130402", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130502", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130702", + "zoneCode": "FLEX", + "laneCode": "C1302", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130802", + "zoneCode": "FLEX", + "laneCode": "C1302", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130902", + "zoneCode": "FLEX", + "laneCode": "D1302", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131102", + "zoneCode": "RESERVE", + "laneCode": "B1302", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140102", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140202", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140302", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140402", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140502", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141102", + "zoneCode": "RESERVE", + "laneCode": "B1402", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020503", + "zoneCode": "FLEX", + "laneCode": "A0203", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030303", + "zoneCode": "FLEX", + "laneCode": "A0303", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030403", + "zoneCode": "FLEX", + "laneCode": "A0303", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030503", + "zoneCode": "FLEX", + "laneCode": "A0303", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031103", + "zoneCode": "CACHE", + "laneCode": "B0303", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040303", + "zoneCode": "FLEX", + "laneCode": "A0403", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040403", + "zoneCode": "FLEX", + "laneCode": "A0403", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040503", + "zoneCode": "FLEX", + "laneCode": "A0403", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041103", + "zoneCode": "CACHE", + "laneCode": "B0403", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050303", + "zoneCode": "FLEX", + "laneCode": "A0503", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050403", + "zoneCode": "FLEX", + "laneCode": "A0503", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050503", + "zoneCode": "FLEX", + "laneCode": "A0503", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051103", + "zoneCode": "CACHE", + "laneCode": "B0503", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060303", + "zoneCode": "FLEX", + "laneCode": "A0603", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060403", + "zoneCode": "FLEX", + "laneCode": "A0603", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060503", + "zoneCode": "FLEX", + "laneCode": "A0603", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061103", + "zoneCode": "CACHE", + "laneCode": "B0603", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070103", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070203", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070303", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070403", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070503", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071103", + "zoneCode": "CACHE", + "laneCode": "B0703", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080103", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080203", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080303", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080403", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080503", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080703", + "zoneCode": "FLEX", + "laneCode": "C0803", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080803", + "zoneCode": "FLEX", + "laneCode": "C0803", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080903", + "zoneCode": "RESERVE", + "laneCode": "D0803", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081103", + "zoneCode": "CACHE", + "laneCode": "B0803", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090103", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090203", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090303", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090403", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090503", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090703", + "zoneCode": "FLEX", + "laneCode": "C0903", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090803", + "zoneCode": "FLEX", + "laneCode": "C0903", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090903", + "zoneCode": "RESERVE", + "laneCode": "D0903", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091103", + "zoneCode": "CACHE", + "laneCode": "B0903", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100103", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100203", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100303", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100403", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100503", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100703", + "zoneCode": "FLEX", + "laneCode": "C1003", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100803", + "zoneCode": "FLEX", + "laneCode": "C1003", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100903", + "zoneCode": "RESERVE", + "laneCode": "D1003", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101103", + "zoneCode": "CACHE", + "laneCode": "B1003", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110103", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110203", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110303", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110403", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110503", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110703", + "zoneCode": "FLEX", + "laneCode": "C1103", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110803", + "zoneCode": "FLEX", + "laneCode": "C1103", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110903", + "zoneCode": "RESERVE", + "laneCode": "D1103", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111103", + "zoneCode": "CACHE", + "laneCode": "B1103", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120103", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120203", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120303", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120403", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120503", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120703", + "zoneCode": "FLEX", + "laneCode": "C1203", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120803", + "zoneCode": "FLEX", + "laneCode": "C1203", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120903", + "zoneCode": "RESERVE", + "laneCode": "D1203", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121103", + "zoneCode": "CACHE", + "laneCode": "B1203", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130103", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130203", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130303", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130403", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130503", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130703", + "zoneCode": "FLEX", + "laneCode": "C1303", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130803", + "zoneCode": "FLEX", + "laneCode": "C1303", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130903", + "zoneCode": "FLEX", + "laneCode": "D1303", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131103", + "zoneCode": "RESERVE", + "laneCode": "B1303", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140103", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140203", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140303", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140403", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140503", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141103", + "zoneCode": "RESERVE", + "laneCode": "B1403", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020504", + "zoneCode": "FLEX", + "laneCode": "A0204", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030304", + "zoneCode": "FLEX", + "laneCode": "A0304", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030404", + "zoneCode": "FLEX", + "laneCode": "A0304", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030504", + "zoneCode": "FLEX", + "laneCode": "A0304", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031104", + "zoneCode": "CACHE", + "laneCode": "B0304", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040304", + "zoneCode": "FLEX", + "laneCode": "A0404", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040404", + "zoneCode": "FLEX", + "laneCode": "A0404", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040504", + "zoneCode": "FLEX", + "laneCode": "A0404", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041104", + "zoneCode": "CACHE", + "laneCode": "B0404", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050304", + "zoneCode": "FLEX", + "laneCode": "A0504", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050404", + "zoneCode": "FLEX", + "laneCode": "A0504", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050504", + "zoneCode": "FLEX", + "laneCode": "A0504", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051104", + "zoneCode": "CACHE", + "laneCode": "B0504", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060304", + "zoneCode": "FLEX", + "laneCode": "A0604", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060404", + "zoneCode": "FLEX", + "laneCode": "A0604", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060504", + "zoneCode": "FLEX", + "laneCode": "A0604", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061104", + "zoneCode": "CACHE", + "laneCode": "B0604", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070104", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070204", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070304", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070404", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070504", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071104", + "zoneCode": "CACHE", + "laneCode": "B0704", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080104", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080204", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080304", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080404", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080504", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080704", + "zoneCode": "FLEX", + "laneCode": "C0804", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080804", + "zoneCode": "FLEX", + "laneCode": "C0804", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080904", + "zoneCode": "RESERVE", + "laneCode": "D0804", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081104", + "zoneCode": "CACHE", + "laneCode": "B0804", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090104", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090204", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090304", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090404", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090504", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090704", + "zoneCode": "FLEX", + "laneCode": "C0904", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090804", + "zoneCode": "FLEX", + "laneCode": "C0904", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090904", + "zoneCode": "RESERVE", + "laneCode": "D0904", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091104", + "zoneCode": "CACHE", + "laneCode": "B0904", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100104", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100204", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100304", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100404", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100504", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100704", + "zoneCode": "FLEX", + "laneCode": "C1004", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100804", + "zoneCode": "FLEX", + "laneCode": "C1004", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100904", + "zoneCode": "RESERVE", + "laneCode": "D1004", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101104", + "zoneCode": "CACHE", + "laneCode": "B1004", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110104", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110204", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110304", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110404", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110504", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110704", + "zoneCode": "FLEX", + "laneCode": "C1104", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110804", + "zoneCode": "FLEX", + "laneCode": "C1104", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110904", + "zoneCode": "RESERVE", + "laneCode": "D1104", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111104", + "zoneCode": "CACHE", + "laneCode": "B1104", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120104", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120204", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120304", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120404", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120504", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120704", + "zoneCode": "FLEX", + "laneCode": "C1204", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120804", + "zoneCode": "FLEX", + "laneCode": "C1204", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120904", + "zoneCode": "RESERVE", + "laneCode": "D1204", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121104", + "zoneCode": "CACHE", + "laneCode": "B1204", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130104", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130204", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130304", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130404", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130504", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130704", + "zoneCode": "FLEX", + "laneCode": "C1304", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130804", + "zoneCode": "FLEX", + "laneCode": "C1304", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130904", + "zoneCode": "FLEX", + "laneCode": "D1304", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131104", + "zoneCode": "RESERVE", + "laneCode": "B1304", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140104", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140204", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140304", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140404", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140504", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141104", + "zoneCode": "RESERVE", + "laneCode": "B1404", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020505", + "zoneCode": "FLEX", + "laneCode": "A0205", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030305", + "zoneCode": "FLEX", + "laneCode": "A0305", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030405", + "zoneCode": "FLEX", + "laneCode": "A0305", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030505", + "zoneCode": "FLEX", + "laneCode": "A0305", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031105", + "zoneCode": "CACHE", + "laneCode": "B0305", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040305", + "zoneCode": "FLEX", + "laneCode": "A0405", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040405", + "zoneCode": "FLEX", + "laneCode": "A0405", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040505", + "zoneCode": "FLEX", + "laneCode": "A0405", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041105", + "zoneCode": "CACHE", + "laneCode": "B0405", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050305", + "zoneCode": "FLEX", + "laneCode": "A0505", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050405", + "zoneCode": "FLEX", + "laneCode": "A0505", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050505", + "zoneCode": "FLEX", + "laneCode": "A0505", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051105", + "zoneCode": "CACHE", + "laneCode": "B0505", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060305", + "zoneCode": "FLEX", + "laneCode": "A0605", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060405", + "zoneCode": "FLEX", + "laneCode": "A0605", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060505", + "zoneCode": "FLEX", + "laneCode": "A0605", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061105", + "zoneCode": "CACHE", + "laneCode": "B0605", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070105", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070205", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070305", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070405", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070505", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071105", + "zoneCode": "CACHE", + "laneCode": "B0705", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080105", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080205", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080305", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080405", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080505", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080705", + "zoneCode": "FLEX", + "laneCode": "C0805", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080805", + "zoneCode": "FLEX", + "laneCode": "C0805", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080905", + "zoneCode": "RESERVE", + "laneCode": "D0805", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081105", + "zoneCode": "CACHE", + "laneCode": "B0805", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090105", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090205", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090305", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090405", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090505", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090705", + "zoneCode": "FLEX", + "laneCode": "C0905", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090805", + "zoneCode": "FLEX", + "laneCode": "C0905", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090905", + "zoneCode": "RESERVE", + "laneCode": "D0905", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091105", + "zoneCode": "CACHE", + "laneCode": "B0905", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100105", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100205", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100305", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100405", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100505", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100705", + "zoneCode": "FLEX", + "laneCode": "C1005", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100805", + "zoneCode": "FLEX", + "laneCode": "C1005", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100905", + "zoneCode": "RESERVE", + "laneCode": "D1005", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101105", + "zoneCode": "CACHE", + "laneCode": "B1005", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110105", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110205", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110305", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110405", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110505", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110705", + "zoneCode": "FLEX", + "laneCode": "C1105", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110805", + "zoneCode": "FLEX", + "laneCode": "C1105", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110905", + "zoneCode": "RESERVE", + "laneCode": "D1105", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111105", + "zoneCode": "CACHE", + "laneCode": "B1105", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120105", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120205", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120305", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120405", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120505", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120705", + "zoneCode": "FLEX", + "laneCode": "C1205", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120805", + "zoneCode": "FLEX", + "laneCode": "C1205", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120905", + "zoneCode": "RESERVE", + "laneCode": "D1205", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121105", + "zoneCode": "CACHE", + "laneCode": "B1205", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130105", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130205", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130305", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130405", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130505", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130705", + "zoneCode": "FLEX", + "laneCode": "C1305", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130805", + "zoneCode": "FLEX", + "laneCode": "C1305", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130905", + "zoneCode": "FLEX", + "laneCode": "D1305", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131105", + "zoneCode": "RESERVE", + "laneCode": "B1305", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140105", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140205", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140305", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140405", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140505", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141105", + "zoneCode": "RESERVE", + "laneCode": "B1405", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020506", + "zoneCode": "FLEX", + "laneCode": "A0206", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030306", + "zoneCode": "FLEX", + "laneCode": "A0306", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030406", + "zoneCode": "FLEX", + "laneCode": "A0306", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030506", + "zoneCode": "FLEX", + "laneCode": "A0306", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031106", + "zoneCode": "CACHE", + "laneCode": "B0306", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040306", + "zoneCode": "FLEX", + "laneCode": "A0406", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040406", + "zoneCode": "FLEX", + "laneCode": "A0406", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040506", + "zoneCode": "FLEX", + "laneCode": "A0406", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041106", + "zoneCode": "CACHE", + "laneCode": "B0406", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050306", + "zoneCode": "FLEX", + "laneCode": "A0506", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050406", + "zoneCode": "FLEX", + "laneCode": "A0506", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050506", + "zoneCode": "FLEX", + "laneCode": "A0506", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051106", + "zoneCode": "CACHE", + "laneCode": "B0506", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060306", + "zoneCode": "FLEX", + "laneCode": "A0606", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060406", + "zoneCode": "FLEX", + "laneCode": "A0606", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060506", + "zoneCode": "FLEX", + "laneCode": "A0606", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061106", + "zoneCode": "CACHE", + "laneCode": "B0606", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070106", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070206", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070306", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070406", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070506", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071106", + "zoneCode": "CACHE", + "laneCode": "B0706", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080106", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080206", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080306", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080406", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080506", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080706", + "zoneCode": "FLEX", + "laneCode": "C0806", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080806", + "zoneCode": "FLEX", + "laneCode": "C0806", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080906", + "zoneCode": "RESERVE", + "laneCode": "D0806", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081106", + "zoneCode": "CACHE", + "laneCode": "B0806", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090106", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090206", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090306", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090406", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090506", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090706", + "zoneCode": "FLEX", + "laneCode": "C0906", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090806", + "zoneCode": "FLEX", + "laneCode": "C0906", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090906", + "zoneCode": "RESERVE", + "laneCode": "D0906", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091106", + "zoneCode": "CACHE", + "laneCode": "B0906", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100106", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100206", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100306", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100406", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100506", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100706", + "zoneCode": "FLEX", + "laneCode": "C1006", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100806", + "zoneCode": "FLEX", + "laneCode": "C1006", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100906", + "zoneCode": "RESERVE", + "laneCode": "D1006", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101106", + "zoneCode": "CACHE", + "laneCode": "B1006", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110106", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110206", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110306", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110406", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110506", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110706", + "zoneCode": "FLEX", + "laneCode": "C1106", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110806", + "zoneCode": "FLEX", + "laneCode": "C1106", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110906", + "zoneCode": "RESERVE", + "laneCode": "D1106", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111106", + "zoneCode": "CACHE", + "laneCode": "B1106", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120106", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120206", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120306", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120406", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120506", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120706", + "zoneCode": "FLEX", + "laneCode": "C1206", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120806", + "zoneCode": "FLEX", + "laneCode": "C1206", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120906", + "zoneCode": "FLEX", + "laneCode": "D1206", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121106", + "zoneCode": "CACHE", + "laneCode": "B1206", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130106", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130206", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130306", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130406", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130506", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130706", + "zoneCode": "FLEX", + "laneCode": "C1306", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130806", + "zoneCode": "FLEX", + "laneCode": "C1306", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130906", + "zoneCode": "FLEX", + "laneCode": "D1306", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131106", + "zoneCode": "RESERVE", + "laneCode": "B1306", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140106", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140206", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140306", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140406", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140506", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141106", + "zoneCode": "RESERVE", + "laneCode": "B1406", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020507", + "zoneCode": "FLEX", + "laneCode": "A0207", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030307", + "zoneCode": "FLEX", + "laneCode": "A0307", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030407", + "zoneCode": "FLEX", + "laneCode": "A0307", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030507", + "zoneCode": "FLEX", + "laneCode": "A0307", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031107", + "zoneCode": "CACHE", + "laneCode": "B0307", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040307", + "zoneCode": "FLEX", + "laneCode": "A0407", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040407", + "zoneCode": "FLEX", + "laneCode": "A0407", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040507", + "zoneCode": "FLEX", + "laneCode": "A0407", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041107", + "zoneCode": "CACHE", + "laneCode": "B0407", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050307", + "zoneCode": "FLEX", + "laneCode": "A0507", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050407", + "zoneCode": "FLEX", + "laneCode": "A0507", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050507", + "zoneCode": "FLEX", + "laneCode": "A0507", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051107", + "zoneCode": "CACHE", + "laneCode": "B0507", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060307", + "zoneCode": "FLEX", + "laneCode": "A0607", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060407", + "zoneCode": "FLEX", + "laneCode": "A0607", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060507", + "zoneCode": "FLEX", + "laneCode": "A0607", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061107", + "zoneCode": "CACHE", + "laneCode": "B0607", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070107", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-BLOCK-1", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-01", + "inboundAt": "2026-07-01T09:00:00+08:00" + }, + { + "spaceId": "070207", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-BLOCK-2", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-01", + "inboundAt": "2026-07-01T10:00:00+08:00" + }, + { + "spaceId": "070307", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-BLOCK-3", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-01", + "inboundAt": "2026-07-01T11:00:00+08:00" + }, + { + "spaceId": "070407", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-BLOCK-4", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-01", + "inboundAt": "2026-07-01T12:00:00+08:00" + }, + { + "spaceId": "070507", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-OLDEST", + "projectNo": "P-FIFO-DEMO", + "productId": "M-FIFO-DEMO", + "lotNo": "FIFO-LOT-01", + "inboundAt": "2026-07-01T08:00:00+08:00" + }, + { + "spaceId": "071107", + "zoneCode": "CACHE", + "laneCode": "B0707", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080107", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080207", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080307", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080407", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080507", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080707", + "zoneCode": "FLEX", + "laneCode": "C0807", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080807", + "zoneCode": "FLEX", + "laneCode": "C0807", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080907", + "zoneCode": "RESERVE", + "laneCode": "D0807", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081107", + "zoneCode": "CACHE", + "laneCode": "B0807", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090107", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090207", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090307", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090407", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090507", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090707", + "zoneCode": "FLEX", + "laneCode": "C0907", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090807", + "zoneCode": "FLEX", + "laneCode": "C0907", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090907", + "zoneCode": "RESERVE", + "laneCode": "D0907", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091107", + "zoneCode": "CACHE", + "laneCode": "B0907", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100107", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100207", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100307", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100407", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100507", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100707", + "zoneCode": "FLEX", + "laneCode": "C1007", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100807", + "zoneCode": "FLEX", + "laneCode": "C1007", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100907", + "zoneCode": "RESERVE", + "laneCode": "D1007", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101107", + "zoneCode": "CACHE", + "laneCode": "B1007", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110107", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110207", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110307", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110407", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110507", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110707", + "zoneCode": "FLEX", + "laneCode": "C1107", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110807", + "zoneCode": "FLEX", + "laneCode": "C1107", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110907", + "zoneCode": "RESERVE", + "laneCode": "D1107", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111107", + "zoneCode": "CACHE", + "laneCode": "B1107", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120107", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120207", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120307", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120407", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120507", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120707", + "zoneCode": "FLEX", + "laneCode": "C1207", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120807", + "zoneCode": "FLEX", + "laneCode": "C1207", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120907", + "zoneCode": "FLEX", + "laneCode": "D1207", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121107", + "zoneCode": "CACHE", + "laneCode": "B1207", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130107", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130207", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130307", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130407", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130507", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130707", + "zoneCode": "FLEX", + "laneCode": "C1307", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130807", + "zoneCode": "FLEX", + "laneCode": "C1307", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130907", + "zoneCode": "FLEX", + "laneCode": "D1307", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131107", + "zoneCode": "RESERVE", + "laneCode": "B1307", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140107", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140207", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140307", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140407", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140507", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141107", + "zoneCode": "RESERVE", + "laneCode": "B1407", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030308", + "zoneCode": "FLEX", + "laneCode": "A0308", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030408", + "zoneCode": "FLEX", + "laneCode": "A0308", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030508", + "zoneCode": "FLEX", + "laneCode": "A0308", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031108", + "zoneCode": "CACHE", + "laneCode": "B0308", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040308", + "zoneCode": "FLEX", + "laneCode": "A0408", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040408", + "zoneCode": "FLEX", + "laneCode": "A0408", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040508", + "zoneCode": "FLEX", + "laneCode": "A0408", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041108", + "zoneCode": "CACHE", + "laneCode": "B0408", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050308", + "zoneCode": "FLEX", + "laneCode": "A0508", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050408", + "zoneCode": "FLEX", + "laneCode": "A0508", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050508", + "zoneCode": "FLEX", + "laneCode": "A0508", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051108", + "zoneCode": "CACHE", + "laneCode": "B0508", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060308", + "zoneCode": "FLEX", + "laneCode": "A0608", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060408", + "zoneCode": "FLEX", + "laneCode": "A0608", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060508", + "zoneCode": "FLEX", + "laneCode": "A0608", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061108", + "zoneCode": "CACHE", + "laneCode": "B0608", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070108", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070208", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070308", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070408", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070508", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071108", + "zoneCode": "CACHE", + "laneCode": "B0708", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080108", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080208", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080308", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080408", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080508", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080708", + "zoneCode": "FLEX", + "laneCode": "C0808", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080808", + "zoneCode": "FLEX", + "laneCode": "C0808", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080908", + "zoneCode": "RESERVE", + "laneCode": "D0808", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081108", + "zoneCode": "CACHE", + "laneCode": "B0808", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090108", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090208", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090308", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090408", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090508", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090708", + "zoneCode": "FLEX", + "laneCode": "C0908", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090808", + "zoneCode": "FLEX", + "laneCode": "C0908", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090908", + "zoneCode": "RESERVE", + "laneCode": "D0908", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091108", + "zoneCode": "CACHE", + "laneCode": "B0908", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100108", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100208", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100308", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100408", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100508", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100708", + "zoneCode": "FLEX", + "laneCode": "C1008", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100808", + "zoneCode": "FLEX", + "laneCode": "C1008", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100908", + "zoneCode": "RESERVE", + "laneCode": "D1008", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101108", + "zoneCode": "CACHE", + "laneCode": "B1008", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110108", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110208", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110308", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110408", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110508", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110708", + "zoneCode": "FLEX", + "laneCode": "C1108", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110808", + "zoneCode": "FLEX", + "laneCode": "C1108", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110908", + "zoneCode": "RESERVE", + "laneCode": "D1108", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111108", + "zoneCode": "CACHE", + "laneCode": "B1108", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120108", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120208", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120308", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120408", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120508", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120708", + "zoneCode": "FLEX", + "laneCode": "C1208", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120808", + "zoneCode": "FLEX", + "laneCode": "C1208", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120908", + "zoneCode": "FLEX", + "laneCode": "D1208", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121108", + "zoneCode": "CACHE", + "laneCode": "B1208", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130108", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130208", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130308", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130408", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130508", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130708", + "zoneCode": "FLEX", + "laneCode": "C1308", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130808", + "zoneCode": "FLEX", + "laneCode": "C1308", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130908", + "zoneCode": "FLEX", + "laneCode": "D1308", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131108", + "zoneCode": "RESERVE", + "laneCode": "B1308", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140108", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140208", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140308", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140408", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140508", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141108", + "zoneCode": "RESERVE", + "laneCode": "B1408", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + } + ], + "expected": { + "planStatus": "READY", + "taskPlanCount": 1, + "plannedCount": 1, + "rejectedCount": 0, + "executionState": "READY_WITH_ELEVATOR_TOKEN", + "trayNo": "FIFO-OLDEST", + "sourceSpaceId": "070507", + "blockerCount": 0, + "blockerSpaceIds": [], + "blockingTrayNos": [], + "fifoMode": "STRICT", + "fifoRank": 1, + "fifoDeviationMinutes": 0, + "fifoViolation": false, + "capacityScore": 100, + "efficiencyScore": 28, + "totalScore": 100 + } + }, + { + "id": "fifo-flexible-outbound", + "kind": "OUTBOUND", + "policy": { + "capacityWeight": 0.5, + "efficiencyWeight": 0.5 + }, + "request": { + "requestId": "OUT-FIFO-FLEXIBLE", + "trayNo": null, + "projectNo": "P-FIFO-DEMO", + "productId": "M-FIFO-DEMO", + "fifoMode": "FLEXIBLE", + "fifoToleranceMinutes": 1440, + "exitFloor": 1 + }, + "spaces": [ + { + "spaceId": "020501", + "zoneCode": "FLEX", + "laneCode": "A0201", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030301", + "zoneCode": "FLEX", + "laneCode": "A0301", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030401", + "zoneCode": "FLEX", + "laneCode": "A0301", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030501", + "zoneCode": "FLEX", + "laneCode": "A0301", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031101", + "zoneCode": "CACHE", + "laneCode": "B0301", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040301", + "zoneCode": "FLEX", + "laneCode": "A0401", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040401", + "zoneCode": "FLEX", + "laneCode": "A0401", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040501", + "zoneCode": "FLEX", + "laneCode": "A0401", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041101", + "zoneCode": "CACHE", + "laneCode": "B0401", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050301", + "zoneCode": "FLEX", + "laneCode": "A0501", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050401", + "zoneCode": "FLEX", + "laneCode": "A0501", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050501", + "zoneCode": "FLEX", + "laneCode": "A0501", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051101", + "zoneCode": "CACHE", + "laneCode": "B0501", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060301", + "zoneCode": "FLEX", + "laneCode": "A0601", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060401", + "zoneCode": "FLEX", + "laneCode": "A0601", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060501", + "zoneCode": "FLEX", + "laneCode": "A0601", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061101", + "zoneCode": "CACHE", + "laneCode": "B0601", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070101", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070201", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070301", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070401", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070501", + "zoneCode": "MAIN", + "laneCode": "A0701", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071101", + "zoneCode": "CACHE", + "laneCode": "B0701", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080101", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-DIRECT-INNER-1", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-02", + "inboundAt": "2026-07-01T12:00:00+08:00" + }, + { + "spaceId": "080201", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-DIRECT-INNER-2", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-02", + "inboundAt": "2026-07-01T12:00:00+08:00" + }, + { + "spaceId": "080301", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-DIRECT-INNER-3", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-02", + "inboundAt": "2026-07-01T12:00:00+08:00" + }, + { + "spaceId": "080401", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-DIRECT-INNER-4", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-02", + "inboundAt": "2026-07-01T12:00:00+08:00" + }, + { + "spaceId": "080501", + "zoneCode": "MAIN", + "laneCode": "A0801", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-DIRECT", + "projectNo": "P-FIFO-DEMO", + "productId": "M-FIFO-DEMO", + "lotNo": "FIFO-LOT-02", + "inboundAt": "2026-07-01T20:00:00+08:00" + }, + { + "spaceId": "080701", + "zoneCode": "FLEX", + "laneCode": "C0801", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080801", + "zoneCode": "FLEX", + "laneCode": "C0801", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080901", + "zoneCode": "RESERVE", + "laneCode": "D0801", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081101", + "zoneCode": "CACHE", + "laneCode": "B0801", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090101", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090201", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090301", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090401", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090501", + "zoneCode": "MAIN", + "laneCode": "A0901", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090701", + "zoneCode": "FLEX", + "laneCode": "C0901", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090801", + "zoneCode": "FLEX", + "laneCode": "C0901", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090901", + "zoneCode": "RESERVE", + "laneCode": "D0901", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091101", + "zoneCode": "CACHE", + "laneCode": "B0901", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100101", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100201", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100301", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100401", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100501", + "zoneCode": "MAIN", + "laneCode": "A1001", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100701", + "zoneCode": "FLEX", + "laneCode": "C1001", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100801", + "zoneCode": "FLEX", + "laneCode": "C1001", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100901", + "zoneCode": "RESERVE", + "laneCode": "D1001", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101101", + "zoneCode": "CACHE", + "laneCode": "B1001", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110101", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110201", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110301", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110401", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110501", + "zoneCode": "MAIN", + "laneCode": "A1101", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110701", + "zoneCode": "FLEX", + "laneCode": "C1101", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110801", + "zoneCode": "FLEX", + "laneCode": "C1101", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110901", + "zoneCode": "RESERVE", + "laneCode": "D1101", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111101", + "zoneCode": "CACHE", + "laneCode": "B1101", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120101", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120201", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120301", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120401", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120501", + "zoneCode": "MAIN", + "laneCode": "A1201", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120701", + "zoneCode": "FLEX", + "laneCode": "C1201", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120801", + "zoneCode": "FLEX", + "laneCode": "C1201", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120901", + "zoneCode": "RESERVE", + "laneCode": "D1201", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121101", + "zoneCode": "CACHE", + "laneCode": "B1201", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130101", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130201", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130301", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130401", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130501", + "zoneCode": "MAIN", + "laneCode": "A1301", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130701", + "zoneCode": "FLEX", + "laneCode": "C1301", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130801", + "zoneCode": "FLEX", + "laneCode": "C1301", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 1, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130901", + "zoneCode": "FLEX", + "laneCode": "D1301", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131101", + "zoneCode": "RESERVE", + "laneCode": "B1301", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140101", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140201", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140301", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140401", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140501", + "zoneCode": "MAIN", + "laneCode": "A1401", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 1, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141101", + "zoneCode": "RESERVE", + "laneCode": "B1401", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 1, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020502", + "zoneCode": "FLEX", + "laneCode": "A0202", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030302", + "zoneCode": "FLEX", + "laneCode": "A0302", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030402", + "zoneCode": "FLEX", + "laneCode": "A0302", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030502", + "zoneCode": "FLEX", + "laneCode": "A0302", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031102", + "zoneCode": "CACHE", + "laneCode": "B0302", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040302", + "zoneCode": "FLEX", + "laneCode": "A0402", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040402", + "zoneCode": "FLEX", + "laneCode": "A0402", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040502", + "zoneCode": "FLEX", + "laneCode": "A0402", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041102", + "zoneCode": "CACHE", + "laneCode": "B0402", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050302", + "zoneCode": "FLEX", + "laneCode": "A0502", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050402", + "zoneCode": "FLEX", + "laneCode": "A0502", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050502", + "zoneCode": "FLEX", + "laneCode": "A0502", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051102", + "zoneCode": "CACHE", + "laneCode": "B0502", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060302", + "zoneCode": "FLEX", + "laneCode": "A0602", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060402", + "zoneCode": "FLEX", + "laneCode": "A0602", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060502", + "zoneCode": "FLEX", + "laneCode": "A0602", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061102", + "zoneCode": "CACHE", + "laneCode": "B0602", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070102", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070202", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070302", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070402", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070502", + "zoneCode": "MAIN", + "laneCode": "A0702", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071102", + "zoneCode": "CACHE", + "laneCode": "B0702", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080102", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080202", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080302", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080402", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080502", + "zoneCode": "MAIN", + "laneCode": "A0802", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080702", + "zoneCode": "FLEX", + "laneCode": "C0802", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080802", + "zoneCode": "FLEX", + "laneCode": "C0802", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080902", + "zoneCode": "RESERVE", + "laneCode": "D0802", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081102", + "zoneCode": "CACHE", + "laneCode": "B0802", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090102", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090202", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090302", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090402", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090502", + "zoneCode": "MAIN", + "laneCode": "A0902", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090702", + "zoneCode": "FLEX", + "laneCode": "C0902", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090802", + "zoneCode": "FLEX", + "laneCode": "C0902", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090902", + "zoneCode": "RESERVE", + "laneCode": "D0902", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091102", + "zoneCode": "CACHE", + "laneCode": "B0902", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100102", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100202", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100302", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100402", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100502", + "zoneCode": "MAIN", + "laneCode": "A1002", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100702", + "zoneCode": "FLEX", + "laneCode": "C1002", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100802", + "zoneCode": "FLEX", + "laneCode": "C1002", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100902", + "zoneCode": "RESERVE", + "laneCode": "D1002", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101102", + "zoneCode": "CACHE", + "laneCode": "B1002", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110102", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110202", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110302", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110402", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110502", + "zoneCode": "MAIN", + "laneCode": "A1102", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110702", + "zoneCode": "FLEX", + "laneCode": "C1102", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110802", + "zoneCode": "FLEX", + "laneCode": "C1102", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110902", + "zoneCode": "RESERVE", + "laneCode": "D1102", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111102", + "zoneCode": "CACHE", + "laneCode": "B1102", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120102", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120202", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120302", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120402", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120502", + "zoneCode": "MAIN", + "laneCode": "A1202", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120702", + "zoneCode": "FLEX", + "laneCode": "C1202", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120802", + "zoneCode": "FLEX", + "laneCode": "C1202", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120902", + "zoneCode": "RESERVE", + "laneCode": "D1202", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121102", + "zoneCode": "CACHE", + "laneCode": "B1202", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130102", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130202", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130302", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130402", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130502", + "zoneCode": "MAIN", + "laneCode": "A1302", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130702", + "zoneCode": "FLEX", + "laneCode": "C1302", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130802", + "zoneCode": "FLEX", + "laneCode": "C1302", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 2, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130902", + "zoneCode": "FLEX", + "laneCode": "D1302", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131102", + "zoneCode": "RESERVE", + "laneCode": "B1302", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140102", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140202", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140302", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140402", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140502", + "zoneCode": "MAIN", + "laneCode": "A1402", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 2, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141102", + "zoneCode": "RESERVE", + "laneCode": "B1402", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 2, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020503", + "zoneCode": "FLEX", + "laneCode": "A0203", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030303", + "zoneCode": "FLEX", + "laneCode": "A0303", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030403", + "zoneCode": "FLEX", + "laneCode": "A0303", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030503", + "zoneCode": "FLEX", + "laneCode": "A0303", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031103", + "zoneCode": "CACHE", + "laneCode": "B0303", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040303", + "zoneCode": "FLEX", + "laneCode": "A0403", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040403", + "zoneCode": "FLEX", + "laneCode": "A0403", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040503", + "zoneCode": "FLEX", + "laneCode": "A0403", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041103", + "zoneCode": "CACHE", + "laneCode": "B0403", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050303", + "zoneCode": "FLEX", + "laneCode": "A0503", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050403", + "zoneCode": "FLEX", + "laneCode": "A0503", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050503", + "zoneCode": "FLEX", + "laneCode": "A0503", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051103", + "zoneCode": "CACHE", + "laneCode": "B0503", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060303", + "zoneCode": "FLEX", + "laneCode": "A0603", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060403", + "zoneCode": "FLEX", + "laneCode": "A0603", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060503", + "zoneCode": "FLEX", + "laneCode": "A0603", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061103", + "zoneCode": "CACHE", + "laneCode": "B0603", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070103", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070203", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070303", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070403", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070503", + "zoneCode": "MAIN", + "laneCode": "A0703", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071103", + "zoneCode": "CACHE", + "laneCode": "B0703", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080103", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080203", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080303", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080403", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080503", + "zoneCode": "MAIN", + "laneCode": "A0803", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080703", + "zoneCode": "FLEX", + "laneCode": "C0803", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080803", + "zoneCode": "FLEX", + "laneCode": "C0803", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080903", + "zoneCode": "RESERVE", + "laneCode": "D0803", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081103", + "zoneCode": "CACHE", + "laneCode": "B0803", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090103", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090203", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090303", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090403", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090503", + "zoneCode": "MAIN", + "laneCode": "A0903", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090703", + "zoneCode": "FLEX", + "laneCode": "C0903", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090803", + "zoneCode": "FLEX", + "laneCode": "C0903", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090903", + "zoneCode": "RESERVE", + "laneCode": "D0903", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091103", + "zoneCode": "CACHE", + "laneCode": "B0903", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100103", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100203", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100303", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100403", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100503", + "zoneCode": "MAIN", + "laneCode": "A1003", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100703", + "zoneCode": "FLEX", + "laneCode": "C1003", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100803", + "zoneCode": "FLEX", + "laneCode": "C1003", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100903", + "zoneCode": "RESERVE", + "laneCode": "D1003", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101103", + "zoneCode": "CACHE", + "laneCode": "B1003", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110103", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110203", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110303", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110403", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110503", + "zoneCode": "MAIN", + "laneCode": "A1103", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110703", + "zoneCode": "FLEX", + "laneCode": "C1103", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110803", + "zoneCode": "FLEX", + "laneCode": "C1103", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110903", + "zoneCode": "RESERVE", + "laneCode": "D1103", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111103", + "zoneCode": "CACHE", + "laneCode": "B1103", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120103", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120203", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120303", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120403", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120503", + "zoneCode": "MAIN", + "laneCode": "A1203", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120703", + "zoneCode": "FLEX", + "laneCode": "C1203", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120803", + "zoneCode": "FLEX", + "laneCode": "C1203", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120903", + "zoneCode": "RESERVE", + "laneCode": "D1203", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121103", + "zoneCode": "CACHE", + "laneCode": "B1203", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130103", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130203", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130303", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130403", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130503", + "zoneCode": "MAIN", + "laneCode": "A1303", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130703", + "zoneCode": "FLEX", + "laneCode": "C1303", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130803", + "zoneCode": "FLEX", + "laneCode": "C1303", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 3, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130903", + "zoneCode": "FLEX", + "laneCode": "D1303", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131103", + "zoneCode": "RESERVE", + "laneCode": "B1303", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140103", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140203", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140303", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140403", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140503", + "zoneCode": "MAIN", + "laneCode": "A1403", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 3, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141103", + "zoneCode": "RESERVE", + "laneCode": "B1403", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 3, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020504", + "zoneCode": "FLEX", + "laneCode": "A0204", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030304", + "zoneCode": "FLEX", + "laneCode": "A0304", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030404", + "zoneCode": "FLEX", + "laneCode": "A0304", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030504", + "zoneCode": "FLEX", + "laneCode": "A0304", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031104", + "zoneCode": "CACHE", + "laneCode": "B0304", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040304", + "zoneCode": "FLEX", + "laneCode": "A0404", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040404", + "zoneCode": "FLEX", + "laneCode": "A0404", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040504", + "zoneCode": "FLEX", + "laneCode": "A0404", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041104", + "zoneCode": "CACHE", + "laneCode": "B0404", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050304", + "zoneCode": "FLEX", + "laneCode": "A0504", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050404", + "zoneCode": "FLEX", + "laneCode": "A0504", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050504", + "zoneCode": "FLEX", + "laneCode": "A0504", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051104", + "zoneCode": "CACHE", + "laneCode": "B0504", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060304", + "zoneCode": "FLEX", + "laneCode": "A0604", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060404", + "zoneCode": "FLEX", + "laneCode": "A0604", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060504", + "zoneCode": "FLEX", + "laneCode": "A0604", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061104", + "zoneCode": "CACHE", + "laneCode": "B0604", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070104", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070204", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070304", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070404", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070504", + "zoneCode": "MAIN", + "laneCode": "A0704", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071104", + "zoneCode": "CACHE", + "laneCode": "B0704", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080104", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080204", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080304", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080404", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080504", + "zoneCode": "MAIN", + "laneCode": "A0804", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080704", + "zoneCode": "FLEX", + "laneCode": "C0804", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080804", + "zoneCode": "FLEX", + "laneCode": "C0804", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080904", + "zoneCode": "RESERVE", + "laneCode": "D0804", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081104", + "zoneCode": "CACHE", + "laneCode": "B0804", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090104", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090204", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090304", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090404", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090504", + "zoneCode": "MAIN", + "laneCode": "A0904", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090704", + "zoneCode": "FLEX", + "laneCode": "C0904", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090804", + "zoneCode": "FLEX", + "laneCode": "C0904", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090904", + "zoneCode": "RESERVE", + "laneCode": "D0904", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091104", + "zoneCode": "CACHE", + "laneCode": "B0904", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100104", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100204", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100304", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100404", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100504", + "zoneCode": "MAIN", + "laneCode": "A1004", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100704", + "zoneCode": "FLEX", + "laneCode": "C1004", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100804", + "zoneCode": "FLEX", + "laneCode": "C1004", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100904", + "zoneCode": "RESERVE", + "laneCode": "D1004", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101104", + "zoneCode": "CACHE", + "laneCode": "B1004", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110104", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110204", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110304", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110404", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110504", + "zoneCode": "MAIN", + "laneCode": "A1104", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110704", + "zoneCode": "FLEX", + "laneCode": "C1104", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110804", + "zoneCode": "FLEX", + "laneCode": "C1104", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110904", + "zoneCode": "RESERVE", + "laneCode": "D1104", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111104", + "zoneCode": "CACHE", + "laneCode": "B1104", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120104", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120204", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120304", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120404", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120504", + "zoneCode": "MAIN", + "laneCode": "A1204", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120704", + "zoneCode": "FLEX", + "laneCode": "C1204", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120804", + "zoneCode": "FLEX", + "laneCode": "C1204", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120904", + "zoneCode": "RESERVE", + "laneCode": "D1204", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121104", + "zoneCode": "CACHE", + "laneCode": "B1204", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130104", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130204", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130304", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130404", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130504", + "zoneCode": "MAIN", + "laneCode": "A1304", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130704", + "zoneCode": "FLEX", + "laneCode": "C1304", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130804", + "zoneCode": "FLEX", + "laneCode": "C1304", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 4, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130904", + "zoneCode": "FLEX", + "laneCode": "D1304", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131104", + "zoneCode": "RESERVE", + "laneCode": "B1304", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140104", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140204", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140304", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140404", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140504", + "zoneCode": "MAIN", + "laneCode": "A1404", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 4, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141104", + "zoneCode": "RESERVE", + "laneCode": "B1404", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 4, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020505", + "zoneCode": "FLEX", + "laneCode": "A0205", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030305", + "zoneCode": "FLEX", + "laneCode": "A0305", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030405", + "zoneCode": "FLEX", + "laneCode": "A0305", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030505", + "zoneCode": "FLEX", + "laneCode": "A0305", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031105", + "zoneCode": "CACHE", + "laneCode": "B0305", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040305", + "zoneCode": "FLEX", + "laneCode": "A0405", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040405", + "zoneCode": "FLEX", + "laneCode": "A0405", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040505", + "zoneCode": "FLEX", + "laneCode": "A0405", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041105", + "zoneCode": "CACHE", + "laneCode": "B0405", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050305", + "zoneCode": "FLEX", + "laneCode": "A0505", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050405", + "zoneCode": "FLEX", + "laneCode": "A0505", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050505", + "zoneCode": "FLEX", + "laneCode": "A0505", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051105", + "zoneCode": "CACHE", + "laneCode": "B0505", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060305", + "zoneCode": "FLEX", + "laneCode": "A0605", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060405", + "zoneCode": "FLEX", + "laneCode": "A0605", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060505", + "zoneCode": "FLEX", + "laneCode": "A0605", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061105", + "zoneCode": "CACHE", + "laneCode": "B0605", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070105", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070205", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070305", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070405", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070505", + "zoneCode": "MAIN", + "laneCode": "A0705", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071105", + "zoneCode": "CACHE", + "laneCode": "B0705", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080105", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080205", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080305", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080405", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080505", + "zoneCode": "MAIN", + "laneCode": "A0805", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080705", + "zoneCode": "FLEX", + "laneCode": "C0805", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080805", + "zoneCode": "FLEX", + "laneCode": "C0805", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080905", + "zoneCode": "RESERVE", + "laneCode": "D0805", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081105", + "zoneCode": "CACHE", + "laneCode": "B0805", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090105", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090205", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090305", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090405", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090505", + "zoneCode": "MAIN", + "laneCode": "A0905", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090705", + "zoneCode": "FLEX", + "laneCode": "C0905", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090805", + "zoneCode": "FLEX", + "laneCode": "C0905", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090905", + "zoneCode": "RESERVE", + "laneCode": "D0905", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091105", + "zoneCode": "CACHE", + "laneCode": "B0905", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100105", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100205", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100305", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100405", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100505", + "zoneCode": "MAIN", + "laneCode": "A1005", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100705", + "zoneCode": "FLEX", + "laneCode": "C1005", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100805", + "zoneCode": "FLEX", + "laneCode": "C1005", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100905", + "zoneCode": "RESERVE", + "laneCode": "D1005", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101105", + "zoneCode": "CACHE", + "laneCode": "B1005", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110105", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110205", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110305", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110405", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110505", + "zoneCode": "MAIN", + "laneCode": "A1105", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110705", + "zoneCode": "FLEX", + "laneCode": "C1105", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110805", + "zoneCode": "FLEX", + "laneCode": "C1105", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110905", + "zoneCode": "RESERVE", + "laneCode": "D1105", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111105", + "zoneCode": "CACHE", + "laneCode": "B1105", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120105", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120205", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120305", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120405", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120505", + "zoneCode": "MAIN", + "laneCode": "A1205", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120705", + "zoneCode": "FLEX", + "laneCode": "C1205", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120805", + "zoneCode": "FLEX", + "laneCode": "C1205", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120905", + "zoneCode": "RESERVE", + "laneCode": "D1205", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121105", + "zoneCode": "CACHE", + "laneCode": "B1205", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130105", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130205", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130305", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130405", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130505", + "zoneCode": "MAIN", + "laneCode": "A1305", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130705", + "zoneCode": "FLEX", + "laneCode": "C1305", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130805", + "zoneCode": "FLEX", + "laneCode": "C1305", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 5, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130905", + "zoneCode": "FLEX", + "laneCode": "D1305", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131105", + "zoneCode": "RESERVE", + "laneCode": "B1305", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140105", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140205", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140305", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140405", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140505", + "zoneCode": "MAIN", + "laneCode": "A1405", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 5, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141105", + "zoneCode": "RESERVE", + "laneCode": "B1405", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 5, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020506", + "zoneCode": "FLEX", + "laneCode": "A0206", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030306", + "zoneCode": "FLEX", + "laneCode": "A0306", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030406", + "zoneCode": "FLEX", + "laneCode": "A0306", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030506", + "zoneCode": "FLEX", + "laneCode": "A0306", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031106", + "zoneCode": "CACHE", + "laneCode": "B0306", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040306", + "zoneCode": "FLEX", + "laneCode": "A0406", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040406", + "zoneCode": "FLEX", + "laneCode": "A0406", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040506", + "zoneCode": "FLEX", + "laneCode": "A0406", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041106", + "zoneCode": "CACHE", + "laneCode": "B0406", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050306", + "zoneCode": "FLEX", + "laneCode": "A0506", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050406", + "zoneCode": "FLEX", + "laneCode": "A0506", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050506", + "zoneCode": "FLEX", + "laneCode": "A0506", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051106", + "zoneCode": "CACHE", + "laneCode": "B0506", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060306", + "zoneCode": "FLEX", + "laneCode": "A0606", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060406", + "zoneCode": "FLEX", + "laneCode": "A0606", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060506", + "zoneCode": "FLEX", + "laneCode": "A0606", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061106", + "zoneCode": "CACHE", + "laneCode": "B0606", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070106", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070206", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070306", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070406", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070506", + "zoneCode": "MAIN", + "laneCode": "A0706", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071106", + "zoneCode": "CACHE", + "laneCode": "B0706", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080106", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080206", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080306", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080406", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080506", + "zoneCode": "MAIN", + "laneCode": "A0806", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080706", + "zoneCode": "FLEX", + "laneCode": "C0806", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080806", + "zoneCode": "FLEX", + "laneCode": "C0806", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080906", + "zoneCode": "RESERVE", + "laneCode": "D0806", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081106", + "zoneCode": "CACHE", + "laneCode": "B0806", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090106", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090206", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090306", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090406", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090506", + "zoneCode": "MAIN", + "laneCode": "A0906", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090706", + "zoneCode": "FLEX", + "laneCode": "C0906", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090806", + "zoneCode": "FLEX", + "laneCode": "C0906", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090906", + "zoneCode": "RESERVE", + "laneCode": "D0906", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091106", + "zoneCode": "CACHE", + "laneCode": "B0906", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100106", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100206", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100306", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100406", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100506", + "zoneCode": "MAIN", + "laneCode": "A1006", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100706", + "zoneCode": "FLEX", + "laneCode": "C1006", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100806", + "zoneCode": "FLEX", + "laneCode": "C1006", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100906", + "zoneCode": "RESERVE", + "laneCode": "D1006", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101106", + "zoneCode": "CACHE", + "laneCode": "B1006", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110106", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110206", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110306", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110406", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110506", + "zoneCode": "MAIN", + "laneCode": "A1106", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110706", + "zoneCode": "FLEX", + "laneCode": "C1106", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110806", + "zoneCode": "FLEX", + "laneCode": "C1106", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110906", + "zoneCode": "RESERVE", + "laneCode": "D1106", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111106", + "zoneCode": "CACHE", + "laneCode": "B1106", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120106", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120206", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120306", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120406", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120506", + "zoneCode": "MAIN", + "laneCode": "A1206", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120706", + "zoneCode": "FLEX", + "laneCode": "C1206", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120806", + "zoneCode": "FLEX", + "laneCode": "C1206", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120906", + "zoneCode": "FLEX", + "laneCode": "D1206", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121106", + "zoneCode": "CACHE", + "laneCode": "B1206", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130106", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130206", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130306", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130406", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130506", + "zoneCode": "MAIN", + "laneCode": "A1306", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130706", + "zoneCode": "FLEX", + "laneCode": "C1306", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130806", + "zoneCode": "FLEX", + "laneCode": "C1306", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 6, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130906", + "zoneCode": "FLEX", + "laneCode": "D1306", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131106", + "zoneCode": "RESERVE", + "laneCode": "B1306", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140106", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140206", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140306", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140406", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140506", + "zoneCode": "MAIN", + "laneCode": "A1406", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 6, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141106", + "zoneCode": "RESERVE", + "laneCode": "B1406", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 6, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "020507", + "zoneCode": "FLEX", + "laneCode": "A0207", + "depthOrder": 5, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "2", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030307", + "zoneCode": "FLEX", + "laneCode": "A0307", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030407", + "zoneCode": "FLEX", + "laneCode": "A0307", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030507", + "zoneCode": "FLEX", + "laneCode": "A0307", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031107", + "zoneCode": "CACHE", + "laneCode": "B0307", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040307", + "zoneCode": "FLEX", + "laneCode": "A0407", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040407", + "zoneCode": "FLEX", + "laneCode": "A0407", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040507", + "zoneCode": "FLEX", + "laneCode": "A0407", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041107", + "zoneCode": "CACHE", + "laneCode": "B0407", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050307", + "zoneCode": "FLEX", + "laneCode": "A0507", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050407", + "zoneCode": "FLEX", + "laneCode": "A0507", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050507", + "zoneCode": "FLEX", + "laneCode": "A0507", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051107", + "zoneCode": "CACHE", + "laneCode": "B0507", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060307", + "zoneCode": "FLEX", + "laneCode": "A0607", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060407", + "zoneCode": "FLEX", + "laneCode": "A0607", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060507", + "zoneCode": "FLEX", + "laneCode": "A0607", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061107", + "zoneCode": "CACHE", + "laneCode": "B0607", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070107", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-BLOCK-1", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-01", + "inboundAt": "2026-07-01T09:00:00+08:00" + }, + { + "spaceId": "070207", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-BLOCK-2", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-01", + "inboundAt": "2026-07-01T10:00:00+08:00" + }, + { + "spaceId": "070307", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-BLOCK-3", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-01", + "inboundAt": "2026-07-01T11:00:00+08:00" + }, + { + "spaceId": "070407", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-BLOCK-4", + "projectNo": "P-FIFO-BLOCK", + "productId": "M-FIFO-BLOCK", + "lotNo": "BLOCK-LOT-01", + "inboundAt": "2026-07-01T12:00:00+08:00" + }, + { + "spaceId": "070507", + "zoneCode": "MAIN", + "laneCode": "A0707", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "OCCUPIED", + "outboundTaskActive": false, + "trayNo": "FIFO-OLDEST", + "projectNo": "P-FIFO-DEMO", + "productId": "M-FIFO-DEMO", + "lotNo": "FIFO-LOT-01", + "inboundAt": "2026-07-01T08:00:00+08:00" + }, + { + "spaceId": "071107", + "zoneCode": "CACHE", + "laneCode": "B0707", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080107", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080207", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080307", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080407", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080507", + "zoneCode": "MAIN", + "laneCode": "A0807", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080707", + "zoneCode": "FLEX", + "laneCode": "C0807", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080807", + "zoneCode": "FLEX", + "laneCode": "C0807", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080907", + "zoneCode": "RESERVE", + "laneCode": "D0807", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081107", + "zoneCode": "CACHE", + "laneCode": "B0807", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090107", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090207", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090307", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090407", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090507", + "zoneCode": "MAIN", + "laneCode": "A0907", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090707", + "zoneCode": "FLEX", + "laneCode": "C0907", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090807", + "zoneCode": "FLEX", + "laneCode": "C0907", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090907", + "zoneCode": "RESERVE", + "laneCode": "D0907", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091107", + "zoneCode": "CACHE", + "laneCode": "B0907", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100107", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100207", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100307", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100407", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100507", + "zoneCode": "MAIN", + "laneCode": "A1007", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100707", + "zoneCode": "FLEX", + "laneCode": "C1007", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100807", + "zoneCode": "FLEX", + "laneCode": "C1007", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100907", + "zoneCode": "RESERVE", + "laneCode": "D1007", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101107", + "zoneCode": "CACHE", + "laneCode": "B1007", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110107", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110207", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110307", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110407", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110507", + "zoneCode": "MAIN", + "laneCode": "A1107", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110707", + "zoneCode": "FLEX", + "laneCode": "C1107", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110807", + "zoneCode": "FLEX", + "laneCode": "C1107", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110907", + "zoneCode": "RESERVE", + "laneCode": "D1107", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111107", + "zoneCode": "CACHE", + "laneCode": "B1107", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120107", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120207", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120307", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120407", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120507", + "zoneCode": "MAIN", + "laneCode": "A1207", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120707", + "zoneCode": "FLEX", + "laneCode": "C1207", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120807", + "zoneCode": "FLEX", + "laneCode": "C1207", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120907", + "zoneCode": "FLEX", + "laneCode": "D1207", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121107", + "zoneCode": "CACHE", + "laneCode": "B1207", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130107", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130207", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130307", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130407", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130507", + "zoneCode": "MAIN", + "laneCode": "A1307", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130707", + "zoneCode": "FLEX", + "laneCode": "C1307", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130807", + "zoneCode": "FLEX", + "laneCode": "C1307", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 7, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130907", + "zoneCode": "FLEX", + "laneCode": "D1307", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131107", + "zoneCode": "RESERVE", + "laneCode": "B1307", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140107", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140207", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140307", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140407", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140507", + "zoneCode": "MAIN", + "laneCode": "A1407", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 7, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141107", + "zoneCode": "RESERVE", + "laneCode": "B1407", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 7, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030308", + "zoneCode": "FLEX", + "laneCode": "A0308", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030408", + "zoneCode": "FLEX", + "laneCode": "A0308", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "030508", + "zoneCode": "FLEX", + "laneCode": "A0308", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "3", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "031108", + "zoneCode": "CACHE", + "laneCode": "B0308", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "3", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040308", + "zoneCode": "FLEX", + "laneCode": "A0408", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040408", + "zoneCode": "FLEX", + "laneCode": "A0408", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "040508", + "zoneCode": "FLEX", + "laneCode": "A0408", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "4", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "041108", + "zoneCode": "CACHE", + "laneCode": "B0408", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "4", + "isCacheCore": true, + "isReserveCore": false, + "role": "OUTBOUND_CACHE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050308", + "zoneCode": "FLEX", + "laneCode": "A0508", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050408", + "zoneCode": "FLEX", + "laneCode": "A0508", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "050508", + "zoneCode": "FLEX", + "laneCode": "A0508", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "051108", + "zoneCode": "CACHE", + "laneCode": "B0508", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "5", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060308", + "zoneCode": "FLEX", + "laneCode": "A0608", + "depthOrder": 1, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060408", + "zoneCode": "FLEX", + "laneCode": "A0608", + "depthOrder": 2, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 2, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "060508", + "zoneCode": "FLEX", + "laneCode": "A0608", + "depthOrder": 3, + "laneCapacity": 3, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 3, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "061108", + "zoneCode": "CACHE", + "laneCode": "B0608", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "6", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070108", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070208", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070308", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070408", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "070508", + "zoneCode": "MAIN", + "laneCode": "A0708", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "071108", + "zoneCode": "CACHE", + "laneCode": "B0708", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "7", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080108", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080208", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080308", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080408", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080508", + "zoneCode": "MAIN", + "laneCode": "A0808", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080708", + "zoneCode": "FLEX", + "laneCode": "C0808", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080808", + "zoneCode": "FLEX", + "laneCode": "C0808", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "080908", + "zoneCode": "RESERVE", + "laneCode": "D0808", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "081108", + "zoneCode": "CACHE", + "laneCode": "B0808", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "8", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090108", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090208", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090308", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090408", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090508", + "zoneCode": "MAIN", + "laneCode": "A0908", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090708", + "zoneCode": "FLEX", + "laneCode": "C0908", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090808", + "zoneCode": "FLEX", + "laneCode": "C0908", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "090908", + "zoneCode": "RESERVE", + "laneCode": "D0908", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "091108", + "zoneCode": "CACHE", + "laneCode": "B0908", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "9", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100108", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100208", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100308", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100408", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100508", + "zoneCode": "MAIN", + "laneCode": "A1008", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100708", + "zoneCode": "FLEX", + "laneCode": "C1008", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100808", + "zoneCode": "FLEX", + "laneCode": "C1008", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "100908", + "zoneCode": "RESERVE", + "laneCode": "D1008", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "101108", + "zoneCode": "CACHE", + "laneCode": "B1008", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "10", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110108", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110208", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110308", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110408", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110508", + "zoneCode": "MAIN", + "laneCode": "A1108", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110708", + "zoneCode": "FLEX", + "laneCode": "C1108", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110808", + "zoneCode": "FLEX", + "laneCode": "C1108", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "110908", + "zoneCode": "RESERVE", + "laneCode": "D1108", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "111108", + "zoneCode": "CACHE", + "laneCode": "B1108", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "11", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120108", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120208", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120308", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120408", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120508", + "zoneCode": "MAIN", + "laneCode": "A1208", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120708", + "zoneCode": "FLEX", + "laneCode": "C1208", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120808", + "zoneCode": "FLEX", + "laneCode": "C1208", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "120908", + "zoneCode": "FLEX", + "laneCode": "D1208", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "121108", + "zoneCode": "CACHE", + "laneCode": "B1208", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "12", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130108", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130208", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130308", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130408", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130508", + "zoneCode": "MAIN", + "laneCode": "A1308", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130708", + "zoneCode": "FLEX", + "laneCode": "C1308", + "depthOrder": 2, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 7, + "groupCoding": 2, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130808", + "zoneCode": "FLEX", + "laneCode": "C1308", + "depthOrder": 1, + "laneCapacity": 2, + "floorNo": 8, + "aisleNo": 8, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "130908", + "zoneCode": "FLEX", + "laneCode": "D1308", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 9, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "131108", + "zoneCode": "RESERVE", + "laneCode": "B1308", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "13", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140108", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 1, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 1, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140208", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 2, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 2, + "groupCoding": 2, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140308", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 3, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 3, + "groupCoding": 3, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140408", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 4, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 4, + "groupCoding": 4, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "140508", + "zoneCode": "MAIN", + "laneCode": "A1408", + "depthOrder": 5, + "laneCapacity": 5, + "floorNo": 8, + "aisleNo": 5, + "groupCoding": 5, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": false, + "role": "STORAGE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + }, + { + "spaceId": "141108", + "zoneCode": "RESERVE", + "laneCode": "B1408", + "depthOrder": 1, + "laneCapacity": 1, + "floorNo": 8, + "aisleNo": 11, + "groupCoding": 1, + "rowCode": "14", + "isCacheCore": false, + "isReserveCore": true, + "role": "PROTECTED_CORE", + "status": "EMPTY", + "outboundTaskActive": false, + "trayNo": null, + "projectNo": null, + "productId": null, + "lotNo": null, + "inboundAt": null + } + ], + "expected": { + "planStatus": "READY", + "taskPlanCount": 1, + "plannedCount": 1, + "rejectedCount": 0, + "executionState": "READY", + "trayNo": "FIFO-DIRECT", + "sourceSpaceId": "080501", + "blockerCount": 0, + "blockerSpaceIds": [], + "blockingTrayNos": [], + "fifoMode": "FLEXIBLE", + "fifoRank": 2, + "fifoDeviationMinutes": 720, + "fifoViolation": false, + "capacityScore": 100, + "efficiencyScore": 100, + "totalScore": 100 + } + } + ] +} diff --git a/fortucky-algorithm/src/test/resources/db/h2/data.sql b/fortucky-algorithm/src/test/resources/db/h2/data.sql new file mode 100644 index 0000000..9332d32 --- /dev/null +++ b/fortucky-algorithm/src/test/resources/db/h2/data.sql @@ -0,0 +1,58 @@ +INSERT INTO BAS_CARGO_SPACE (CARGO_SPACE_ID, WAREHOUSE_ID, ROADWAY_ID, CARGO_AREA_ID, CARGO_SPACE_NAME, THE_PLATOON, THE_COLUMN, THE_FLOOR, STATUS, LOCKED, TRAY_CODE, GROUP_CODING_NO, GROUP_CODING) VALUES +('DENSE-1', 'W1', 'R1', 'A', 'Dense inner', 1, 1, 1, '1', '', NULL, 'DENSE-1', '1'), +('DENSE-2', 'W1', 'R1', 'A', 'Dense outer', 1, 2, 1, '1', '', NULL, 'DENSE-1', '2'), +('OUT-INNER', 'W1', 'R2', 'A', 'Outbound inner', 2, 1, 1, '2', '', 'TRAY-OUT', 'OUT-1', '1'), +('OUT-OUTER', 'W1', 'R2', 'A', 'Outbound outer', 2, 2, 1, '1', '', NULL, 'OUT-1', '2'), +('BUFFER-1', 'W1', 'R3', 'E', 'Same floor buffer', 3, 1, 1, '1', '', NULL, 'BUFFER-1', '1'), +('CONFLICT-1', 'W1', 'R4', 'A', 'Conflict space', 4, 1, 1, '2', '', 'TRAY-C1', 'CONFLICT-1', '1'), +('GAP-INNER', 'W1', 'R5', 'C', 'Temporary inner', 5, 1, 1, '5', '', NULL, 'GAP-1', '1'), +('GAP-OUTER', 'W1', 'R5', 'C', 'Temporary outer', 5, 2, 1, '2', '', 'TRAY-GAP', 'GAP-1', '2'), +('LOCKED-1', 'W1', 'R6', 'A', 'Locked', 6, 1, 1, '1', '1', NULL, 'LOCKED-1', '1'), +('INVALID-DEPTH', 'W1', 'R7', 'A', 'Invalid depth', 7, 1, 1, '1', '', NULL, 'INVALID-1', 'X'), +('AVAILABLE-1', 'W1', 'R8', 'A', 'Available inner', 8, 1, 1, '1', '', NULL, 'AVAILABLE-1', '1'), +('AVAILABLE-2', 'W1', 'R8', 'A', 'Available outer', 8, 2, 1, '1', '', NULL, 'AVAILABLE-1', '2'); + +INSERT INTO BAS_STOCK (STOCK_ID, CARGO_SPACE_ID, TRAY_CODE, SPARE4, PRODUCT_ID, LOT_NO, IN_DATE, QUANTITY, OUT_QUANTITY) VALUES +('S-OUT-1', 'OUT-INNER', 'TRAY-OUT', 'P-OUT', 'SKU-OUT', 'LOT-OUT', '2026-01-01 08:00:00', 10, 0), +('S-CONFLICT-1', 'CONFLICT-1', 'TRAY-C1', 'P-ONE', 'SKU-1', 'LOT-1', '2026-01-02 08:00:00', 10, 0), +('S-CONFLICT-2', 'CONFLICT-1', 'TRAY-C2', 'P-TWO', 'SKU-2', 'LOT-2', '2026-01-03 08:00:00', 10, 0), +('S-GAP-1', 'GAP-OUTER', 'TRAY-GAP', 'P-GAP', 'SKU-GAP', 'LOT-GAP', '2026-01-04 08:00:00', 10, 0); + +INSERT INTO ALG_INVENTORY_ITEM_SNAPSHOT ( + WAREHOUSE_ID, STOCK_ID, SPACE_ID, TRAY_CODE, PROJECT_NO, PRODUCT_NO, LOT_NO, + INBOUND_TIME_RAW, INBOUND_AT, QUANTITY, OUT_QUANTITY) +SELECT C.WAREHOUSE_ID, S.STOCK_ID, S.CARGO_SPACE_ID, S.TRAY_CODE, S.SPARE4, S.PRODUCT_ID, + S.LOT_NO, S.IN_DATE, ALG_TRY_TIMESTAMP(S.IN_DATE), S.QUANTITY, S.OUT_QUANTITY +FROM BAS_STOCK S +JOIN BAS_CARGO_SPACE C ON C.CARGO_SPACE_ID = S.CARGO_SPACE_ID; + +INSERT INTO ALG_SPACE_INVENTORY_SUMMARY ( + WAREHOUSE_ID, SPACE_ID, STOCK_DETAIL_COUNT, STOCK_TRAY_COUNT, + STOCK_PROJECT_COUNT, STOCK_PRODUCT_COUNT) +SELECT WAREHOUSE_ID, SPACE_ID, COUNT(*), + COUNT(DISTINCT NULLIF(TRIM(TRAY_CODE), '')), + COUNT(DISTINCT NULLIF(TRIM(PROJECT_NO), '')), + COUNT(DISTINCT NULLIF(TRIM(PRODUCT_NO), '')) +FROM ALG_INVENTORY_ITEM_SNAPSHOT +GROUP BY WAREHOUSE_ID, SPACE_ID; + +INSERT INTO MYDO_JOB (JOB_ID, TASK_NO, TRAY_CODE, CARGO_SPACE_ID, TARGET_CARGO_SPACE_ID, WAREHOUSE_ID, STATUS, IN_OR_OUT, CREATE_TIME, FINISH_TIME) VALUES +('JOB-OUT-1', 'TASK-OUT-1', 'TRAY-OUT', 'OUT-INNER', NULL, 'W1', '3', 21, '2026-01-05 08:00:00', ''), +('JOB-IN-1', 'TASK-IN-1', NULL, NULL, 'DENSE-1', 'W1', '1', 1, '2026-01-05 09:00:00', ''); + +INSERT INTO ALG_SPACE_ROLE (SPACE_ID, ROLE) VALUES ('BUFFER-1', 'RELOCATION_BUFFER'); +INSERT INTO ALG_SPACE_TOPOLOGY (WAREHOUSE_ID, SPACE_ID, LANE_CODE, LANE_DEPTH, BASE_ZONE) VALUES +('W1','DENSE-1','DENSE-1',2,'FLEX'), +('W1','DENSE-2','DENSE-1',2,'FLEX'), +('W1','OUT-INNER','OUT-1',2,'FLEX'), +('W1','OUT-OUTER','OUT-1',2,'FLEX'), +('W1','BUFFER-1','BUFFER-1',1,'CACHE'), +('W1','CONFLICT-1','CONFLICT-1',1,'CACHE'), +('W1','GAP-INNER','GAP-1',2,'FLEX'), +('W1','GAP-OUTER','GAP-1',2,'FLEX'), +('W1','LOCKED-1','LOCKED-1',1,'CACHE'), +('W1','INVALID-DEPTH','INVALID-1',1,'CACHE'), +('W1','AVAILABLE-1','AVAILABLE-1',2,'FLEX'), +('W1','AVAILABLE-2','AVAILABLE-1',2,'FLEX'); +INSERT INTO ALG_LANE_STATE (WAREHOUSE_ID, LANE_CODE, SPACE_COUNT, OCCUPIED_COUNT, AVAILABLE_COUNT, PENDING_OUTBOUND, HAS_GAP, STATE_VERSION) +VALUES ('W1', 'DENSE-1', 2, 0, 1, FALSE, FALSE, 7); diff --git a/fortucky-algorithm/src/test/resources/db/h2/schema.sql b/fortucky-algorithm/src/test/resources/db/h2/schema.sql new file mode 100644 index 0000000..b6d5c99 --- /dev/null +++ b/fortucky-algorithm/src/test/resources/db/h2/schema.sql @@ -0,0 +1,348 @@ +CREATE TABLE BAS_CARGO_SPACE ( + CARGO_SPACE_ID VARCHAR(80) PRIMARY KEY, + WAREHOUSE_ID VARCHAR(80) NOT NULL, + ROADWAY_ID VARCHAR(80), + CARGO_AREA_ID VARCHAR(80), + CARGO_SPACE_NAME VARCHAR(80), + THE_PLATOON INT, + THE_COLUMN INT, + THE_FLOOR INT, + STATUS VARCHAR(5), + LOCKED VARCHAR(5), + TRAY_CODE VARCHAR(255), + GROUP_CODING_NO VARCHAR(80), + GROUP_CODING VARCHAR(80) +); + +CREATE TABLE BAS_STOCK ( + STOCK_ID VARCHAR(32) PRIMARY KEY, + CARGO_SPACE_ID VARCHAR(80), + TRAY_CODE VARCHAR(225), + SPARE4 VARCHAR(255), + PRODUCT_ID VARCHAR(255), + LOT_NO VARCHAR(80), + IN_DATE VARCHAR(80), + QUANTITY DECIMAL(30, 0), + OUT_QUANTITY DECIMAL(30, 0) +); + +CREATE TABLE MYDO_JOB ( + JOB_ID VARCHAR(80) PRIMARY KEY, + TASK_NO VARCHAR(80), + TRAY_CODE VARCHAR(225), + CARGO_SPACE_ID VARCHAR(80), + TARGET_CARGO_SPACE_ID VARCHAR(80), + WAREHOUSE_ID VARCHAR(80), + STATUS VARCHAR(255), + IN_OR_OUT INT, + CREATE_TIME VARCHAR(80), + FINISH_TIME VARCHAR(80) +); + +CREATE TABLE ALG_WAREHOUSE_POLICY ( + WAREHOUSE_ID VARCHAR(80) PRIMARY KEY, + TARGET_FILL_RATE DECIMAL(9, 4), + FIFO_TOLERANCE_HOURS INT, + UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE ALG_PROJECT_POLICY ( + PROJECT_NO VARCHAR(255) PRIMARY KEY, + IS_ISOLATED BOOLEAN NOT NULL DEFAULT FALSE, + IS_COMMON BOOLEAN NOT NULL DEFAULT FALSE, + ALLOW_MIXED BOOLEAN NOT NULL DEFAULT FALSE, + UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE ALG_SPACE_ROLE ( + SPACE_ID VARCHAR(80) PRIMARY KEY, + ROLE VARCHAR(40) NOT NULL, + UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + CHECK (ROLE IN ('STORAGE', 'RELOCATION_BUFFER', 'OUTBOUND_BUFFER', 'PROTECTED_CORE')) +); + +CREATE TABLE ALG_SPACE_TOPOLOGY ( + WAREHOUSE_ID VARCHAR(80) NOT NULL, + SPACE_ID VARCHAR(80) PRIMARY KEY, + LANE_CODE VARCHAR(80) NOT NULL, + LANE_DEPTH INT NOT NULL, + BASE_ZONE VARCHAR(20) NOT NULL, + REBUILT_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + CHECK (BASE_ZONE IN ('CACHE', 'RESERVE', 'MAIN', 'FLEX')) +); + +CREATE INDEX ALG_IX_SPACE_TOPOLOGY_WAREHOUSE_LANE ON ALG_SPACE_TOPOLOGY (WAREHOUSE_ID, LANE_CODE); + +CREATE TABLE ALG_INVENTORY_ITEM_SNAPSHOT ( + WAREHOUSE_ID VARCHAR(80) NOT NULL, + STOCK_ID VARCHAR(80) NOT NULL, + SPACE_ID VARCHAR(80) NOT NULL, + TRAY_CODE VARCHAR(255), + PROJECT_NO VARCHAR(255), + PRODUCT_NO VARCHAR(255), + LOT_NO VARCHAR(80), + INBOUND_TIME_RAW VARCHAR(80), + INBOUND_AT TIMESTAMP, + QUANTITY DECIMAL(38, 6), + OUT_QUANTITY DECIMAL(38, 6), + SYNCHRONIZED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (WAREHOUSE_ID, STOCK_ID) +); + +CREATE INDEX ALG_IX_INVENTORY_ITEM_SNAPSHOT_SPACE + ON ALG_INVENTORY_ITEM_SNAPSHOT (WAREHOUSE_ID, SPACE_ID); +CREATE INDEX ALG_IX_INVENTORY_ITEM_SNAPSHOT_TRAY + ON ALG_INVENTORY_ITEM_SNAPSHOT (WAREHOUSE_ID, TRAY_CODE); +CREATE INDEX ALG_IX_INVENTORY_ITEM_SNAPSHOT_PROJECT_PRODUCT + ON ALG_INVENTORY_ITEM_SNAPSHOT (WAREHOUSE_ID, PROJECT_NO, PRODUCT_NO); + +CREATE TABLE ALG_SPACE_INVENTORY_SUMMARY ( + WAREHOUSE_ID VARCHAR(80) NOT NULL, + SPACE_ID VARCHAR(80) NOT NULL, + STOCK_DETAIL_COUNT INT NOT NULL, + STOCK_TRAY_COUNT INT NOT NULL, + STOCK_PROJECT_COUNT INT NOT NULL, + STOCK_PRODUCT_COUNT INT NOT NULL, + SYNCHRONIZED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (WAREHOUSE_ID, SPACE_ID) +); + +CREATE TABLE ALG_LANE_STATE ( + WAREHOUSE_ID VARCHAR(80) NOT NULL, + LANE_CODE VARCHAR(80) NOT NULL, + SPACE_COUNT INT NOT NULL DEFAULT 0, + OCCUPIED_COUNT INT NOT NULL DEFAULT 0, + AVAILABLE_COUNT INT NOT NULL DEFAULT 0, + PENDING_OUTBOUND BOOLEAN NOT NULL DEFAULT FALSE, + HAS_GAP BOOLEAN NOT NULL DEFAULT FALSE, + SEMANTIC_FINGERPRINT VARCHAR(64) NOT NULL DEFAULT '', + STATE_VERSION BIGINT NOT NULL DEFAULT 0, + REBUILT_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (WAREHOUSE_ID, LANE_CODE) +); + +CREATE TABLE ALG_RESERVATION ( + RESERVATION_ID VARCHAR(80) PRIMARY KEY, + WAREHOUSE_ID VARCHAR(80) NOT NULL, + LANE_CODE VARCHAR(80) NOT NULL, + SPACE_ID VARCHAR(80) NOT NULL, + PROJECT_NO VARCHAR(255), + STATUS VARCHAR(20) NOT NULL, + ACTIVE_SPACE_GUARD VARCHAR(200) GENERATED ALWAYS AS (CASE WHEN STATUS = 'ACTIVE' THEN 'A:' || SPACE_ID ELSE 'H:' || RESERVATION_ID END), + CREATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + RELEASED_AT TIMESTAMP, + CHECK (STATUS IN ('ACTIVE', 'RELEASED', 'EXPIRED')) +); + +CREATE UNIQUE INDEX ALG_UQ_ACTIVE_RESERVATION_SPACE ON ALG_RESERVATION (ACTIVE_SPACE_GUARD); + +CREATE TABLE ALG_DEEP_WORKFLOW_LOCK ( + LOCK_ID VARCHAR(80) PRIMARY KEY, + REQUEST_ID VARCHAR(80) NOT NULL, + WAREHOUSE_ID VARCHAR(80) NOT NULL, + FLOOR_NO INT NOT NULL, + STATUS VARCHAR(20) NOT NULL, + ACTIVE_FLOOR_GUARD VARCHAR(200) GENERATED ALWAYS AS ( + CASE WHEN STATUS = 'ACTIVE' THEN WAREHOUSE_ID || ':' || FLOOR_NO ELSE LOCK_ID END), + CREATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + RELEASED_AT TIMESTAMP, + CHECK (STATUS IN ('ACTIVE', 'RELEASED')) +); + +CREATE UNIQUE INDEX ALG_UQ_ACTIVE_DEEP_WORKFLOW_FLOOR ON ALG_DEEP_WORKFLOW_LOCK (ACTIVE_FLOOR_GUARD); + +CREATE TABLE ALG_DECISION_LOG ( + DECISION_ID VARCHAR(80) PRIMARY KEY, + WAREHOUSE_ID VARCHAR(80), + DECISION_TYPE VARCHAR(40) NOT NULL, + INPUT_VERSION BIGINT, + RESULT_CODE VARCHAR(80), + REASON VARCHAR(2000), + CREATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +CREATE ALIAS ALG_TRY_TIMESTAMP AS $$ +java.sql.Timestamp algTryTimestamp(String value) { + if (value == null) return null; + try { + java.time.format.DateTimeFormatter formatter = new java.time.format.DateTimeFormatterBuilder() + .appendPattern("uuuu-MM-dd HH:mm:ss") + .optionalStart().appendFraction(java.time.temporal.ChronoField.NANO_OF_SECOND, 0, 9, true).optionalEnd() + .toFormatter().withResolverStyle(java.time.format.ResolverStyle.STRICT); + return java.sql.Timestamp.valueOf(java.time.LocalDateTime.parse(value, formatter)); + } catch (RuntimeException exception) { + return null; + } +} +$$; + +CREATE VIEW ALG_V_INVENTORY_ITEM AS +SELECT + STOCK_ID, SPACE_ID, TRAY_CODE, PROJECT_NO, PRODUCT_NO, LOT_NO, + INBOUND_TIME_RAW, INBOUND_AT, QUANTITY, OUT_QUANTITY +FROM ALG_INVENTORY_ITEM_SNAPSHOT; + +CREATE VIEW ALG_V_ACTIVE_JOB AS +WITH TRAY_CANDIDATES AS ( + SELECT J.JOB_ID, + COUNT(DISTINCT S.SPACE_ID) AS SPACE_COUNT, + MIN(S.SPACE_ID) AS CARGO_SPACE_ID, + COUNT(DISTINCT NULLIF(TRIM(S.PROJECT_NO), '')) AS PROJECT_COUNT, + MIN(NULLIF(TRIM(S.PROJECT_NO), '')) AS PROJECT_NO, + COUNT(DISTINCT NULLIF(TRIM(S.PRODUCT_NO), '')) AS PRODUCT_COUNT, + MIN(NULLIF(TRIM(S.PRODUCT_NO), '')) AS PRODUCT_NO + FROM MYDO_JOB J + JOIN ALG_INVENTORY_ITEM_SNAPSHOT S ON S.WAREHOUSE_ID = J.WAREHOUSE_ID + AND S.TRAY_CODE = NULLIF(TRIM(J.TRAY_CODE), '') + GROUP BY J.JOB_ID +), +RESOLVED_JOBS AS ( + SELECT J.JOB_ID, J.TASK_NO, J.TRAY_CODE, J.TARGET_CARGO_SPACE_ID, J.WAREHOUSE_ID, + J.STATUS, J.IN_OR_OUT, J.CREATE_TIME AS CREATE_TIME_RAW, + COALESCE(SOURCE_SPACE.CARGO_SPACE_ID, + CASE WHEN TRAY_CANDIDATES.SPACE_COUNT = 1 THEN TRAY_CANDIDATES.CARGO_SPACE_ID END) AS SOURCE_SPACE_ID, + CASE WHEN SOURCE_SPACE.CARGO_SPACE_ID IS NOT NULL THEN 'EXPLICIT' + WHEN TRAY_CANDIDATES.SPACE_COUNT = 1 THEN 'TRAY' + WHEN TRAY_CANDIDATES.SPACE_COUNT > 1 THEN 'AMBIGUOUS_TRAY' + ELSE 'UNRESOLVED' END AS SOURCE_RESOLUTION + FROM MYDO_JOB J + LEFT JOIN BAS_CARGO_SPACE SOURCE_SPACE ON SOURCE_SPACE.CARGO_SPACE_ID = NULLIF(TRIM(J.CARGO_SPACE_ID), '') + AND SOURCE_SPACE.WAREHOUSE_ID = J.WAREHOUSE_ID + LEFT JOIN TRAY_CANDIDATES ON TRAY_CANDIDATES.JOB_ID = J.JOB_ID + WHERE J.FINISH_TIME IS NULL OR TRIM(J.FINISH_TIME) = '' +), +SOURCE_SCOPE AS ( + SELECT R.JOB_ID, + COUNT(DISTINCT NULLIF(TRIM(S.PROJECT_NO), '')) AS PROJECT_COUNT, + MIN(NULLIF(TRIM(S.PROJECT_NO), '')) AS PROJECT_NO, + COUNT(DISTINCT NULLIF(TRIM(S.PRODUCT_NO), '')) AS PRODUCT_COUNT, + MIN(NULLIF(TRIM(S.PRODUCT_NO), '')) AS PRODUCT_NO + FROM RESOLVED_JOBS R + JOIN ALG_INVENTORY_ITEM_SNAPSHOT S ON S.WAREHOUSE_ID = R.WAREHOUSE_ID + AND S.SPACE_ID = R.SOURCE_SPACE_ID + GROUP BY R.JOB_ID +) +SELECT R.JOB_ID, R.TASK_NO, R.TRAY_CODE, + CASE WHEN R.SOURCE_SPACE_ID IS NOT NULL + THEN CASE WHEN SOURCE_SCOPE.PROJECT_COUNT = 1 THEN SOURCE_SCOPE.PROJECT_NO END + ELSE CASE WHEN TRAY_CANDIDATES.PROJECT_COUNT = 1 THEN TRAY_CANDIDATES.PROJECT_NO END END AS PROJECT_NO, + CASE WHEN R.SOURCE_SPACE_ID IS NOT NULL + THEN CASE WHEN SOURCE_SCOPE.PRODUCT_COUNT = 1 THEN SOURCE_SCOPE.PRODUCT_NO END + ELSE CASE WHEN TRAY_CANDIDATES.PRODUCT_COUNT = 1 THEN TRAY_CANDIDATES.PRODUCT_NO END END AS PRODUCT_NO, + R.SOURCE_SPACE_ID, R.TARGET_CARGO_SPACE_ID, R.WAREHOUSE_ID, R.STATUS, R.IN_OR_OUT, + R.CREATE_TIME_RAW, RESOLVED_SPACE.GROUP_CODING_NO AS SOURCE_LANE_CODE, R.SOURCE_RESOLUTION +FROM RESOLVED_JOBS R +LEFT JOIN TRAY_CANDIDATES ON TRAY_CANDIDATES.JOB_ID = R.JOB_ID +LEFT JOIN SOURCE_SCOPE ON SOURCE_SCOPE.JOB_ID = R.JOB_ID +LEFT JOIN BAS_CARGO_SPACE RESOLVED_SPACE ON RESOLVED_SPACE.CARGO_SPACE_ID = R.SOURCE_SPACE_ID; + +CREATE VIEW ALG_V_SPACE_STATE AS +WITH OUTBOUND_LANES AS ( + SELECT DISTINCT WAREHOUSE_ID, SOURCE_LANE_CODE AS LANE_CODE + FROM ALG_V_ACTIVE_JOB + WHERE IN_OR_OUT >= 20 AND SOURCE_LANE_CODE IS NOT NULL +), +ACTIVE_RESERVATIONS AS ( + SELECT SPACE_ID, MIN(RESERVATION_ID) AS RESERVATION_ID + FROM ALG_RESERVATION + WHERE STATUS = 'ACTIVE' + GROUP BY SPACE_ID +), +SPACE_DEPTH AS ( + SELECT CARGO_SPACE_ID, WAREHOUSE_ID, GROUP_CODING_NO, STATUS, + CASE WHEN GROUP_CODING REGEXP '^[0-9]+$' THEN CAST(GROUP_CODING AS INT) END AS DEPTH + FROM BAS_CARGO_SPACE +), +LANE_GAPS AS ( + SELECT DISTINCT INNER_SPACE.WAREHOUSE_ID, INNER_SPACE.GROUP_CODING_NO AS LANE_CODE + FROM BAS_CARGO_SPACE INNER_SPACE + JOIN BAS_CARGO_SPACE OUTER_SPACE + ON OUTER_SPACE.WAREHOUSE_ID = INNER_SPACE.WAREHOUSE_ID + AND OUTER_SPACE.GROUP_CODING_NO = INNER_SPACE.GROUP_CODING_NO + AND CASE WHEN OUTER_SPACE.GROUP_CODING REGEXP '^[0-9]+$' THEN CAST(OUTER_SPACE.GROUP_CODING AS INT) END + > CASE WHEN INNER_SPACE.GROUP_CODING REGEXP '^[0-9]+$' THEN CAST(INNER_SPACE.GROUP_CODING AS INT) END + WHERE CASE WHEN INNER_SPACE.GROUP_CODING REGEXP '^[0-9]+$' THEN CAST(INNER_SPACE.GROUP_CODING AS INT) END IS NOT NULL + AND CASE WHEN OUTER_SPACE.GROUP_CODING REGEXP '^[0-9]+$' THEN CAST(OUTER_SPACE.GROUP_CODING AS INT) END IS NOT NULL + AND NULLIF(TRIM(INNER_SPACE.TRAY_CODE), '') IS NULL + AND NOT EXISTS ( + SELECT 1 FROM ALG_INVENTORY_ITEM_SNAPSHOT INNER_STOCK + WHERE INNER_STOCK.WAREHOUSE_ID = INNER_SPACE.WAREHOUSE_ID + AND INNER_STOCK.SPACE_ID = INNER_SPACE.CARGO_SPACE_ID + ) + AND ( + NULLIF(TRIM(OUTER_SPACE.TRAY_CODE), '') IS NOT NULL + OR EXISTS ( + SELECT 1 FROM ALG_INVENTORY_ITEM_SNAPSHOT OUTER_STOCK + WHERE OUTER_STOCK.WAREHOUSE_ID = OUTER_SPACE.WAREHOUSE_ID + AND OUTER_STOCK.SPACE_ID = OUTER_SPACE.CARGO_SPACE_ID + ) + ) +) +SELECT + C.CARGO_SPACE_ID AS SPACE_ID, + C.WAREHOUSE_ID, + C.GROUP_CODING_NO AS LANE_CODE, + C.CARGO_AREA_ID AS AREA_ID, + CASE + WHEN COALESCE(R.ROLE, 'STORAGE') IN ('RELOCATION_BUFFER', 'OUTBOUND_BUFFER') THEN 'CACHE' + WHEN COALESCE(R.ROLE, 'STORAGE') = 'PROTECTED_CORE' THEN 'RESERVE' + ELSE TOPOLOGY.BASE_ZONE + END AS ZONE_CODE, + C.ROADWAY_ID, + C.CARGO_SPACE_NAME AS DISPLAY_NAME, + C.THE_PLATOON AS PLATOON, + C.THE_COLUMN AS COLUMN_NO, + C.THE_FLOOR AS FLOOR_NO, + C.GROUP_CODING AS DEPTH_RAW, + SPACE_DEPTH.DEPTH, + C.STATUS AS SPACE_STATUS, + C.LOCKED, + C.TRAY_CODE AS SPACE_TRAY_CODE, + COALESCE(R.ROLE, 'STORAGE') AS ROLE, + COALESCE(STOCK.STOCK_DETAIL_COUNT, 0) AS STOCK_DETAIL_COUNT, + COALESCE(STOCK.STOCK_TRAY_COUNT, 0) AS STOCK_TRAY_COUNT, + COALESCE(STOCK.STOCK_PROJECT_COUNT, 0) AS STOCK_PROJECT_COUNT, + COALESCE(STOCK.STOCK_PRODUCT_COUNT, 0) AS STOCK_PRODUCT_COUNT, + COALESCE(STOCK.STOCK_TRAY_COUNT, 0) > 1 AS TRAY_CONFLICT, + COALESCE(STOCK.STOCK_PROJECT_COUNT, 0) > 1 AS PROJECT_CONFLICT, + FALSE AS PRODUCT_CONFLICT, + OUTBOUND_LANES.LANE_CODE IS NOT NULL AS PENDING_OUTBOUND, + ACTIVE_RESERVATIONS.RESERVATION_ID, + ACTIVE_RESERVATIONS.RESERVATION_ID IS NOT NULL AS RESERVED, + LANE_GAPS.LANE_CODE IS NOT NULL AS HAS_GAP, + CASE + WHEN C.STATUS IS NULL OR C.STATUS <> '1' THEN FALSE + WHEN NULLIF(TRIM(C.LOCKED), '') IS NOT NULL AND TRIM(C.LOCKED) NOT IN ('0', 'N') THEN FALSE + WHEN NULLIF(TRIM(C.TRAY_CODE), '') IS NOT NULL THEN FALSE + WHEN COALESCE(STOCK.STOCK_DETAIL_COUNT, 0) <> 0 THEN FALSE + WHEN SPACE_DEPTH.DEPTH IS NULL THEN FALSE + WHEN COALESCE(R.ROLE, 'STORAGE') <> 'STORAGE' THEN FALSE + WHEN OUTBOUND_LANES.LANE_CODE IS NOT NULL THEN FALSE + WHEN ACTIVE_RESERVATIONS.RESERVATION_ID IS NOT NULL THEN FALSE + WHEN LANE_GAPS.LANE_CODE IS NOT NULL THEN FALSE + WHEN EXISTS ( + SELECT 1 + FROM BAS_CARGO_SPACE INNER_CANDIDATE + LEFT JOIN ALG_SPACE_INVENTORY_SUMMARY INNER_STOCK + ON INNER_STOCK.WAREHOUSE_ID = INNER_CANDIDATE.WAREHOUSE_ID + AND INNER_STOCK.SPACE_ID = INNER_CANDIDATE.CARGO_SPACE_ID + WHERE INNER_CANDIDATE.WAREHOUSE_ID = C.WAREHOUSE_ID + AND INNER_CANDIDATE.GROUP_CODING_NO = C.GROUP_CODING_NO + AND CASE WHEN INNER_CANDIDATE.GROUP_CODING REGEXP '^[0-9]+$' THEN CAST(INNER_CANDIDATE.GROUP_CODING AS INT) END < SPACE_DEPTH.DEPTH + AND INNER_CANDIDATE.STATUS = '1' + AND NULLIF(TRIM(INNER_CANDIDATE.TRAY_CODE), '') IS NULL + AND INNER_STOCK.SPACE_ID IS NULL + ) THEN FALSE + ELSE TRUE + END AS INBOUND_AVAILABLE +FROM BAS_CARGO_SPACE C +JOIN ALG_SPACE_TOPOLOGY TOPOLOGY ON TOPOLOGY.SPACE_ID = C.CARGO_SPACE_ID +LEFT JOIN SPACE_DEPTH ON SPACE_DEPTH.CARGO_SPACE_ID = C.CARGO_SPACE_ID +LEFT JOIN ALG_SPACE_INVENTORY_SUMMARY STOCK ON STOCK.WAREHOUSE_ID = C.WAREHOUSE_ID + AND STOCK.SPACE_ID = C.CARGO_SPACE_ID +LEFT JOIN ALG_SPACE_ROLE R ON R.SPACE_ID = C.CARGO_SPACE_ID +LEFT JOIN OUTBOUND_LANES ON OUTBOUND_LANES.WAREHOUSE_ID = C.WAREHOUSE_ID + AND OUTBOUND_LANES.LANE_CODE = C.GROUP_CODING_NO +LEFT JOIN ACTIVE_RESERVATIONS ON ACTIVE_RESERVATIONS.SPACE_ID = C.CARGO_SPACE_ID +LEFT JOIN LANE_GAPS ON LANE_GAPS.WAREHOUSE_ID = C.WAREHOUSE_ID + AND LANE_GAPS.LANE_CODE = C.GROUP_CODING_NO; diff --git a/pom.xml b/pom.xml index 796e05e..17b0923 100644 --- a/pom.xml +++ b/pom.xml @@ -191,6 +191,20 @@ ${ruoyi.version} + + + com.ruoyi + ruoyi-license + ${ruoyi.version} + + + + + com.ruoyi + fortucky-algorithm + ${ruoyi.version} + + org.springframework.ai spring-ai-bom @@ -243,6 +257,8 @@ ruoyi-quartz ruoyi-generator ruoyi-common + ruoyi-license + fortucky-algorithm
pom @@ -251,7 +267,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.13.0 + 3.11.0 true ${java.version} @@ -259,6 +275,11 @@ ${project.build.sourceEncoding} + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + org.springframework.boot spring-boot-maven-plugin diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index c3d5860..69d6ef3 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -54,6 +54,18 @@ ruoyi-generator + + + com.ruoyi + ruoyi-license + + + + + com.ruoyi + fortucky-algorithm + + org.springframework.ai spring-ai-starter-model-openai diff --git a/ruoyi-admin/src/main/java/com/ruoyi/Dzp/DzpSend.java b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/DzpSend.java new file mode 100644 index 0000000..916ae55 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/DzpSend.java @@ -0,0 +1,120 @@ +package com.ruoyi.Dzp; + + +import com.ruoyi.Dzp.domain.basLed; +import com.ruoyi.Dzp.mapper.BasLedMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; +import java.util.List; + +@RestController +@RequestMapping("/api2dzp") +public class DzpSend { + @Autowired + private BasLedMapper mapper; + + + @Scheduled(fixedDelay = 1000) + public void InLed() throws IOException { + basLed basLed = new basLed(); + basLed.setSendFlag("0"); + basLed.setId(1); + List basLeds = mapper.selectBasLedList(basLed); + if (basLeds != null && basLeds.size() > 0 && (basLeds.get(0).getModel().equals("1") || basLeds.get(0).getModel().equals("2"))) { + MyUdpSocket myUdpSocket = new MyUdpSocket(6666); + ProtocolDemo.my_udp = myUdpSocket; + String ip = basLeds.get(0).getIpAddress(); + String msgProductTitle = "物资编码:"; + String msgProduct = basLeds.get(0).getProduct_id(); + String msgSpecTitle = "物资规格:"; + String msgSpec = basLeds.get(0).getSpec(); + String msg3 = "托盘条码:" + basLeds.get(0).getTrayCode(); + String msg4 = null; + if (basLeds.get(0).getModel().equals("1")) { + msg4 = "入库数量:"; + } else { + msg4 = "出库数量:"; + } + String ms7 = "物资名称:"; + String msg8 = basLeds.get(0).getProductName(); + String msgQuantity = basLeds.get(0).getQuantity(); + if (ProtocolDemo.demo_play_chapterschedule4(ip, msgProductTitle, msgSpecTitle, msg4, msg3, msgSpec, msgProduct, ms7, msg8, msgQuantity)) { + basLeds.get(0).setSendFlag("1"); + mapper.updateBasLed(basLeds.get(0)); + } + myUdpSocket.close(); + + } + basLed basLed2 = new basLed(); + basLed2.setSendFlag("0"); + basLed2.setId(2); + List basLeds2 = mapper.selectBasLedList(basLed2); + if (basLeds2 != null && basLeds2.size() > 0 && (basLeds2.get(0).getModel().equals("1") || basLeds2.get(0).getModel().equals("2"))) { + MyUdpSocket myUdpSocket = new MyUdpSocket(6666); + ProtocolDemo.my_udp = myUdpSocket; + + String ip = basLeds2.get(0).getIpAddress(); + String msgProductTitle = "物资编码:"; + String msgProduct = basLeds2.get(0).getProduct_id(); + String msgSpecTitle = "物资规格:"; + String msgSpec = basLeds2.get(0).getSpec(); + String msg3 = "托盘条码:" + basLeds2.get(0).getTrayCode(); + String msg4 = null; + if (basLeds2.get(0).getModel().equals("1")) { + msg4 = "入库数量:"; + } else { + msg4 = "出库数量:"; + } + String ms7 = "物资名称:"; + String msg8 = basLeds2.get(0).getProductName(); + String msgQuantity = basLeds2.get(0).getQuantity(); + if (ProtocolDemo.demo_play_chapterschedule4(ip, msgProductTitle, msgSpecTitle, msg4, msg3, msgSpec, msgProduct, ms7, msg8, msgQuantity)) { + basLeds2.get(0).setSendFlag("1"); + mapper.updateBasLed(basLeds2.get(0)); + } + + myUdpSocket.close(); + + } + + + } + + + @Scheduled(fixedDelay = 1000) + public void ErrorLed() throws IOException { + basLed basLed = new basLed(); + basLed.setSendFlag("0"); + basLed.setId(1); + List basLeds = mapper.selectBasLedList(basLed); + if (basLeds != null && basLeds.size() > 0 && basLeds.get(0).getModel().equals("3")) { + MyUdpSocket myUdpSocket = new MyUdpSocket(6666); + ProtocolDemo.my_udp = myUdpSocket; + String ip = basLeds.get(0).getIpAddress(); + if (ProtocolDemo.demo_play_chapterschedule2(ip, "报警信息", basLeds.get(0).getErrorMsg())) { + basLeds.get(0).setSendFlag("1"); + mapper.updateBasLed(basLeds.get(0)); + } + myUdpSocket.close(); + + } + basLed basLed2 = new basLed(); + basLed2.setSendFlag("0"); + basLed2.setId(2); + List basLeds2 = mapper.selectBasLedList(basLed2); + if (basLeds2 != null && basLeds2.size() > 0 && basLeds2.get(0).getModel().equals("3")) { + MyUdpSocket myUdpSocket = new MyUdpSocket(6666); + ProtocolDemo.my_udp = myUdpSocket; + String ip = basLeds2.get(0).getIpAddress(); + if (ProtocolDemo.demo_play_chapterschedule2(ip, "报警信息", basLeds2.get(0).getErrorMsg())) { + basLeds2.get(0).setSendFlag("1"); + mapper.updateBasLed(basLeds2.get(0)); + } + myUdpSocket.close(); + } + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/Dzp/LEDSender2010.java b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/LEDSender2010.java new file mode 100644 index 0000000..88daa12 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/LEDSender2010.java @@ -0,0 +1,3235 @@ +package com.ruoyi.Dzp; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.font.FontRenderContext; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Calendar; + +public class LEDSender2010 { + + // ====���붯����ʽ�б�(��ֵ��0��ʼ)==== + // 0 = '���', + // 1 = '������ʾ', + // 2 = '�����ʾ', + // 3 = '�Ϲ���ʾ', + // 4 = '�ҹ���ʾ', + // 5 = '�¹���ʾ', + // 6 = '���������ʾ', + // 7 = '�����Ϲ���ʾ', + // 8 = '�����ҹ���ʾ', + // 9 = '�����¹���ʾ', + // 10 = '�м�������չ��', + // 11 = '�м�������չ��', + // 12 = '�м�������չ��', + // 13 = '������������', + // 14 = '������������', + // 15 = '��������չ��', + // 16 = '��������չ��', + // 17 = '�����Ͻ�����', + // 18 = '�����½�����', + // 19 = '�����Ͻ�����', + // 20 = '�����½�����', + // 21 = '������������', + // 22 = '������������', + // 23 = '�����Ҷ��', + // 24 = '�����Ҷ��', + // ===================================== + + // ====����������ʽ�б�(��ֵ��0��ʼ)==== + // 0 = '���', + // 1 = '����ʧ', + // 2 = '������ʧ', + // 3 = '�������м��£', + // 4 = '�������м��£', + // 5 = '�������м��£', + // 6 = '���������Ƴ�', + // 7 = '���������Ƴ�', + // 8 = '���������£', + // 9 = '�������Һ�£', + // 10 = '�����Ͻ��Ƴ�', + // 11 = '�����½��Ƴ�', + // 12 = '�����Ͻ��Ƴ�', + // 13 = '�����½��Ƴ�', + // 14 = '���������Ƴ�', + // 15 = '���������Ƴ�', + // 16 = '�����Ҷ��', + // 17 = '�����Ҷ��' + // ===================================== + + // ====ͣ��������ʽ�б�(��ֵ��0��ʼ)==== + // 0 = '��̬��ʾ', + // 1 = '��˸��ʾ' + // ===================================== + + public static final int PKP_PREFIX = 0x55; + public static final int PKP_SUFFIX = 0xAA; + public static final int PKP_FILLCH = 0xBB; + + public static final int ALIGN_LEFT = 0x0; + public static final int ALIGN_TOP = 0x0; + public static final int ALIGN_CENTER = 0x1; + public static final int ALIGN_RIGHT = 0x2; + public static final int ALIGN_BOTTOM = 0x2; + + public static final int ROOT_PLAY = 0x21; //��Ŀ���ݣ����浽RAM�����綪ʧ + public static final int ROOT_DOWNLOAD = 0x22; //��Ŀ���ݣ����浽Flash + public static final int ROOT_PLAY_CHAPTER = 0x23; //������߸���ijһĻ + public static final int ROOT_DOWNLOAD_CHAPTER = 0x24; + public static final int ROOT_PLAY_REGION = 0x25; //������߸���ijһ���� + public static final int ROOT_DOWNLOAD_REGION = 0x26; + public static final int ROOT_PLAY_LEAF = 0x27; //������߸���ijһҳ�� + public static final int ROOT_DOWNLOAD_LEAF = 0x28; + public static final int ROOT_PLAY_OBJECT = 0x29; //������߸���ijһ���� + public static final int ROOT_DOWNLOAD_OBJECT = 0x2a; + + public static final int COLOR_TYPE_DOUBLE = 0x2; + public static final int COLOR_TYPE_THREE = 0x3; + public static final int COLOR_TYPE_FULL = 0x4; + + public static final int BITMAP_RED = 0x1; + public static final int BITMAP_GREEN = 0x2; + public static final int BITMAP_YELLOW = 0x3; + public static final int BITMAP_COLOR = 0x4; + public static final int BITMAP_RGB = 0x3; + public static final int BITMAP_FULLCOLOR = 0x5; + + public static final int PKC_BEGIN = 0; + public static final int PKC_END = 1; + public static final int PKC_DATA = 2; + public static final int PKC_RESPOND = 3; + public static final int PKC_NOTIFY = 100; + + public static final int PKC_ADJUST_TIME = 6; + public static final int PKC_GET_PARAM = 7; + public static final int PKC_SET_PARAM = 8; + public static final int PKC_GET_POWER = 9; + public static final int PKC_SET_POWER = 10; + public static final int PKC_GET_BRIGHT = 11; + public static final int PKC_SET_BRIGHT = 12; + public static final int PKC_COM_TRANSFER = 21; + public static final int PKC_SET_SWITCH = 27; + public static final int PKC_GET_POWER_SCHEDULE = 60; + public static final int PKC_SET_POWER_SCHEDULE = 61; + public static final int PKC_RESET_DISPLAY = 99; + + public static final int OBJECT_CHAPTER = 0x3F; + public static final int OBJECT_REGION = 0x3E; + public static final int OBJECT_LEAF = 0x30; + public static final int OBJECT_WINDOW = 0x31; + public static final int OBJECT_DCLOCK = 0x32; + public static final int OBJECT_STRING = 0x33; + public static final int OBJECT_STRING_DCLOCK = 0x35; + public static final int OBJECT_PIXELS = 0x36; + public static final int OBJECT_PIXELSET = 0x37; + public static final int OBJECT_WINDOWS = 0x3B; + public static final int OBJECT_STRINGS = 0x3C; + public static final int OBJECT_SCHEDULE_WINDOW = 0x3E; + public static final int OBJECT_VOICE = 0x5F; + + public static final int DF_YEAR = 1; + public static final int DF_MONTH = 2; + public static final int DF_DAY = 3; + public static final int DF_WEEK = 4; + public static final int DF_HOUR = 5; + public static final int DF_MINUTE = 6; + public static final int DF_SECOND = 7; + public static final int DF_USER = 8; + + public static final int NOTIFY_ROOT_DOWNLOAD = 0x00010003; //����Flash���Ž�Ŀ + public static final int NOTIFY_ROOT_PLAY = 0x00020003; //����Flash���Ž�Ŀ + + /* + typedef struct PKG_HEADER{ + WORD Command; + BYTE srcAddr; + BYTE dstAddr; + DWORD SerialNo; + }TPKG_Header, *PPKG_Header; + */ + static final int PKG_HEADER_STRUCT_SIZE = 8; //2+1+1+4 + static final int PKG_HEADER_COMMAND_OFFSET = 0; + static final int PKG_HEADER_SRCADDR_OFFSET = 2; + static final int PKG_HEADER_DSTADDR_OFFSET = 3; + static final int PKG_HEADER_SERIALNO_OFFSET = 4; + + /* + typedef struct _SYSTEMTIME { + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; + } SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME; + */ + static final int SYSTEMTIME_SIZE = 16; + static final int SYSTEMTIME_YEAR_OFFSET = 0; + static final int SYSTEMTIME_MONTH_OFFSET = 2; + static final int SYSTEMTIME_WEEK_OFFSET = 4; + static final int SYSTEMTIME_DAY_OFFSET = 6; + static final int SYSTEMTIME_HOUR_OFFSET = 8; + static final int SYSTEMTIME_MINUTE_OFFSET = 10; + static final int SYSTEMTIME_SECOND_OFFSET = 12; + static final int SYSTEMTIME_MSECOND_OFFSET = 14; + + /* + TPowerSchedule = packed record + Enabled: DWord; + Mode: DWord; + OpenTime: array [0..20] of TTimeStamp; + CloseTime: array [0..20] of TTimeStamp; + Checksum: DWord; + end; + PPowerSchedule = ^TPowerSchedule; + */ + static final int PWOERSCHEDULE_SIZE = 348; + static final int PWOERSCHEDULE_ENABLED_OFFSET = 0; + static final int PWOERSCHEDULE_MODE_OFFSET = 4; + static final int PWOERSCHEDULE_OPENTIME_OFFSET = 8; + static final int PWOERSCHEDULE_CLOSETIME_OFFSET = 176; + static final int PWOERSCHEDULE_SUNDAY_OPENTIME_OFFSET = 8; + static final int PWOERSCHEDULE_SUNDAY_CLOSETIME_OFFSET = 176; + static final int PWOERSCHEDULE_MONDAY_OPENTIME_OFFSET = 32; + static final int PWOERSCHEDULE_MONDAY_CLOSETIME_OFFSET = 200; + static final int PWOERSCHEDULE_TUESDAY_OPENTIME_OFFSET = 56; + static final int PWOERSCHEDULE_TUESDAY_CLOSETIME_OFFSET = 224; + static final int PWOERSCHEDULE_WEDNESDAY_OPENTIME_OFFSET = 80; + static final int PWOERSCHEDULE_WEDNESDAY_CLOSETIME_OFFSET = 248; + static final int PWOERSCHEDULE_THURSDAY_OPENTIME_OFFSET = 104; + static final int PWOERSCHEDULE_THURSDAY_CLOSETIME_OFFSET = 272; + static final int PWOERSCHEDULE_FRIDAY_OPENTIME_OFFSET = 128; + static final int PWOERSCHEDULE_FRIDAY_CLOSETIME_OFFSET = 296; + static final int PWOERSCHEDULE_SATURDAY_OPENTIME_OFFSET = 152; + static final int PWOERSCHEDULE_SATURDAY_CLOSETIME_OFFSET = 320; + + /* + //������ͷ�� + typedef struct ROOT{ + WORD id; + WORD color; + DWORD size; + DWORD count; + long survive; + WORD flag; + WORD Reserved; + }TRoot, *PRoot; + */ + static final int ROOT_STRUCT_SIZE = 20; //2+2+4+4+4+2+2 + static final int ROOT_COLORTYPE_OFFSET = 2; + static final int ROOT_SIZE_OFFSET = 4; + static final int ROOT_COUNT_OFFSET = 8; + static final int ROOT_SURVIVE_OFFSET = 12; + static final int ROOT_FLAG_OFFSET = 16; + + /* + //�ֲ�ˢ�²������ݽṹ���� + typedef struct CUSTOMACTION{ + TRoot header; //������ͷ�� + WORD actionmode; //����ģʽ(����/�滻) + WORD chapterindex; //���ĸ��½ڲ�������滻 + WORD regionindex; //���ĸ����򴰲�������滻 + WORD leafindex; //���ĸ�ҳ���������滻 + WORD objectindex; //���ĸ�λ�ò�������滻�ؼ� + WORD reserved; + }TCustomAction, *PCustomAction; + */ + static final int ROOT_SUB_STRUCT_SIZE = ROOT_STRUCT_SIZE + 12; //2+2+4+4+4+2+2 + static final int ROOT_SUB_ACTION_MODE = 0; + static final int ROOT_SUB_CHAPTER_INDEX = 2; + static final int ROOT_SUB_REGION_INDEX = 4; + static final int ROOT_SUB_LEAF_INDEX = 6; + static final int ROOT_SUB_OBJECT_INDEX = 8; + + /* + typedef struct PLAYSCHEDULE{ + WORD kind; //���żƻ�����0=ʼ�ղ��ţ�1=��ÿ����ֹʱ�䲥�ţ�3=��ָ������ֹ����ʱ�䲥�� + WORD week; //�����յ���������Ч + TTimeStamp fromtime; //��ʼʱ�� + TTimeStamp totime; //����ʱ�� + }TPlaySchedule, *PPlaySchedule; + */ + static final int PLAY_SCHEDULE_SIZE = 20; + static final int PLAY_SCHEDULE_KIND_OFFSET = 0; + static final int PLAY_SCHEDULE_WEEK_OFFSET = 2; + static final int PLAY_SCHEDULE_FROMTIME_OFFSET = 4; + static final int PLAY_SCHEDULE_FROMDATE_OFFSET = 8; + static final int PLAY_SCHEDULE_TOTIME_OFFSET = 12; + static final int PLAY_SCHEDULE_TODATE_OFFSET = 16; + /* + //�½����ݽṹ�� + typedef struct CHAPTER{ + WORD id; //��ʶ����������У�� + WORD no; //��Ŀ��ţ���0 + WORD wait; //�Ƿ�ȴ��������(=1�ȴ�; =0��ʱ�����) + WORD repeat; //��Ŀ���Ŵ�����Ԥ��δʵ�֣���0 + WORD count; //�߼��������� + BYTE compress; //�Ƿ�ѹ����Ԥ��δʵ�֣���0 + BYTE priority; //���ȼ���Ԥ��δʵ�֣���0 + DWORD time; //��Ŀ��ʾʱ������λ���� + DWORD size; //��ʶ�ý�Ŀ�ֽ���(���������ֽ����͸�Ԫ�ر����ֽ���֮��) + TPlaySchedule schedule; //���żƻ� + }TChapter, *PChapter; + */ + static final int CHAPTER_STRUCT_SIZE = 20 + PLAY_SCHEDULE_SIZE; //2+2+2+2+2+1+1+4+4+PLAY_SCHEDULE_SIZE + static final int CHAPTER_SIZE_OFFSET = 16; + static final int CHAPTER_COUNT_OFFSET = 8; + static final int CHAPTER_WAIT_OFFSET = 4; + static final int CHAPTER_PRIORITY_OFFSET = 11; + static final int CHAPTER_TIME_OFFSET = 12; + static final int CHAPTER_PLAY_SCHEDULE_KIND_OFFSET = 20 + PLAY_SCHEDULE_KIND_OFFSET; + static final int CHAPTER_PLAY_SCHEDULE_WEEK_OFFSET = 20 + PLAY_SCHEDULE_WEEK_OFFSET; + static final int CHAPTER_PLAY_SCHEDULE_FROMTIME_OFFSET = 20 + PLAY_SCHEDULE_FROMTIME_OFFSET; + static final int CHAPTER_PLAY_SCHEDULE_FROMDATE_OFFSET = 20 + PLAY_SCHEDULE_FROMDATE_OFFSET; + static final int CHAPTER_PLAY_SCHEDULE_TOTIME_OFFSET = 20 + PLAY_SCHEDULE_TOTIME_OFFSET; + static final int CHAPTER_PLAY_SCHEDULE_TODATE_OFFSET = 20 + PLAY_SCHEDULE_TODATE_OFFSET; + + /* + //�������ݽṹ�� + typedef struct REGION{ + WORD id; //��ʶ����������У�� + WORD no; //�߼����ڱ�ţ���0 + WORD over; //��Ŀ�Ƿ񲥷����(��modeΪ�ȴ����󲥷����ʱ�����ֶ���Ч���Լ�������ֶ���Ч) + WORD count; //ҳ����Ŀ + DWORD size; //��ʶ���߼������ֽ���(���������ֽ����͸�Ԫ�ر����ֽ���֮��) + TRect rect; //�߼�����λ�ô�С + BYTE border; + BYTE Reserved1; + WORD Reserved2; + }TRegion, *PRegion; + */ + static final int REGION_STRUCT_SIZE = 32; //2+2+2+2+4+16+1+1+2 + static final int REGION_SIZE_OFFSET = 8; + static final int REGION_COUNT_OFFSET = 6; + static final int REGION_LEFT_OFFSET = 12; + static final int REGION_TOP_OFFSET = 16; + static final int REGION_RIGHT_OFFSET = 20; + static final int REGION_BOTTOM_OFFSET = 24; + + /* + //ҳ�����ݽṹ�� + typedef struct LEAF{ + WORD id; //ҳ����(��ҳ���滻ʱ�����ݴ˱���滻) + WORD no; + WORD wait; //�Ƿ�ȴ��������(=1�ȴ�; =0��ʱ�����) + WORD serial; //�Ƿ��з�ʽ���ţ���0 + WORD count; //������Ŀ + WORD Reserved; + DWORD time; //ҳ����ʾʱ�� + DWORD size; //��ʶ��ҳ���ֽ���(���������ֽ����͸�Ԫ�ر����ֽ���֮��) + WORD Reserved1; + WORD Reserved2; + }TLeaf, *PLeaf; + */ + static final int LEAF_STRUCT_SIZE = 24; //2+2+2+2+2+2+4+4+2+2 + static final int LEAF_SIZE_OFFSET = 16; + static final int LEAF_COUNT_OFFSET = 8; + static final int LEAF_WAIT_OFFSET = 4; + static final int LEAF_TIME_OFFSET = 12; + + /* + //����ͨ�����Խṹ�� + typedef struct OBJECT{ + WORD id; //�����ʶ + BYTE transparent; //�Ƿ�͸�� + BYTE flag; //һЩ����λ + DWORD size; //�����ֽ��� + TRect rect; //������ʾ���� + }TObject, *PObject; + */ + static final int OBJECT_STRUCT_SIZE = 24; //2+1+1+4+16 + static final int OBJECT_TRANSPARENT_OFFSET = 2; + static final int OBJECT_SIZE_OFFSET = 4; + static final int OBJECT_LEFT_OFFSET = 8; + static final int OBJECT_TOP_OFFSET = 12; + static final int OBJECT_RIGHT_OFFSET = 16; + static final int OBJECT_BOTTOM_OFFSET = 20; + + /* + //�ಥ�Ŷ������ݽṹ����������TWindow������߶��TString���� + typedef struct WINDOWS{ + TObject object; //�����һ�㶨�� + BYTE method; //������ʽ + BYTE speed; //�����ٶ� + WORD count; //�����ĵ�Window���� + }TWindows, *PWindows; + */ + static final int STRINGS_STRUCT_SIZE = OBJECT_STRUCT_SIZE + 4; //1+1+2 + static final int STRINGS_COUNT_OFFSET = OBJECT_STRUCT_SIZE + 2; + static final int WINDOWS_STRUCT_SIZE = OBJECT_STRUCT_SIZE + 4; //1+1+2 + static final int WINDOWS_COUNT_OFFSET = OBJECT_STRUCT_SIZE + 2; + + /* + //�������ֶ��� + typedef struct STRING{ + WORD id; + BYTE inMethod; //���뷽ʽ + BYTE outMethod; //������ʽ + BYTE stopMethod; //ͣ����ʽ + BYTE alignment; //���뷽ʽ + WORD inSpeed; //�����ٶ� + WORD outSpeed; //�����ٶ� + WORD stopSpeed; //ͣ���ٶ�(����Ϊ��˸ʱ����ʾ��˸�ٶ�) + DWORD stoptime; //ͣ��ʱ�� + long stopx; //ͣ��λ�� + DWORD size; //���ݳ��� + DWORD color; //�ַ���ɫ + WORD fontset; //�ַ���(һ����� 0=16���� 1=24����) + WORD Reserved2; + }TString, *PString; + */ + static final int STRING_STRUCT_SIZE = 32; //2+1+1+1+1+2+2+2+4+4+4+4+2+2 + static final int STRING_IN_METHOD_OFFSET = 2; + static final int STRING_OUT_METHOD_OFFSET = 3; + static final int STRING_STOP_METHOD_OFFSET = 4; + static final int STRING_IN_SPEED_OFFSET = 6; + static final int STRING_OUT_SPEED_OFFSET = 8; + static final int STRING_STOP_SPEED_OFFSET = 10; + static final int STRING_STOP_TIME_OFFSET = 12; + static final int STRING_SIZE_OFFSET = 20; + static final int STRING_COLOR_OFFSET = 24; + static final int STRING_FONT_SET_OFFSET = 28; + + /* + //��������ʱ����� + typedef struct STRINGDCLOCK{ + TObject object; //�����һ�㶨�� + BYTE type; //���ͣ�����ʱ�䡢��սʱ�� + BYTE direct; //����=0������=1��ʱ����ת90�ȣ�=2˳ʱ����ת90�� + WORD step; //���� + TTimeStamp basetime; //��׼ʱ��(��սʱ��ʹ��) + TTimeStamp fromtime; //��ʼʱ��(��սʱ��ʹ��) + TTimeStamp totime; //����ʱ��(��սʱ��ʹ��) + long year_offset; //��ƫ���� + long month_offset; //��ƫ���� + long day_offset; //��ƫ���� + long time_offset; //ʱ��ƫ����(����) + WORD formats[MAX_DATETIME_FORMAT]; //��ʾ��ʽ[32] + DWORD color; + BYTE fontset; + BYTE reserved; + WORD reserved2; + }TStringDClock, *PStringDClock; + */ + static final int SDCLOCK_STRUCT_SIZE = OBJECT_STRUCT_SIZE+116; //2+1+1+1+1+2+2+2+4+4+4+4+2+2 + static final int SDCLOCK_FORMAT_OFFSET = 44; + static final int SDCLOCK_COLOR_OFFSET = 108; + static final int SDCLOCK_FONTSET_OFFSET = 112; + + /* + //����ʱ����� + typedef struct DClock{ + TObject object; //�����һ�㶨�� + BYTE type; //���ͣ�����ʱ�䡢��սʱ�� + BYTE direct; //����=0������=1��ʱ����ת90�ȣ�=2˳ʱ����ת90�� + WORD step; //���� + TTimeStamp basetime; //��׼ʱ��(��սʱ��ʹ��) + TTimeStamp fromtime; //��ʼʱ��(��սʱ��ʹ��) + TTimeStamp totime; //����ʱ��(��սʱ��ʹ��) + long year_offset; //��ƫ���� + long month_offset; //��ƫ���� + long day_offset; //��ƫ���� + long time_offset; //ʱ��ƫ����(����) + WORD formats[MAX_DATETIME_FORMAT]; //��ʾ��ʽ + }TDClock, *PDClock; + */ + static final int DCLOCK_STRUCT_SIZE = OBJECT_STRUCT_SIZE+108; //2+1+1+1+1+2+2+2+4+4+4+4+2+2 + static final int DCLOCK_FORMAT_OFFSET = 44; + + /* + //����ʱ������ʱ���� + typedef struct COUNTER{ + TObject object; + TTimeStamp basetime; + WORD type; + WORD format; + WORD Reserved1; + WORD Reserved2; + }TCounter, *PCounter; + */ + static final int COUNTER_STRUCT_SIZE = OBJECT_STRUCT_SIZE+24; //2+1+1+1+1+2+2+2+4+4+4+4+2+2 + static final int COUNTER_BASETIME_OFFSET = 0; + static final int COUNTER_TYPE_OFFSET = 8; + static final int COUNTER_FORMAT_OFFSET = 10; + + /* + //�������Ŷ��� + typedef struct VOICE{ + TObject object; //�����һ�㶨�� + DWORD interval; + DWORD times; + BYTE voice_speaker; + BYTE voice_volumn; + BYTE voice_tone; + BYTE voice_speed; + DWORD reversed[4]; + }TVoice, *PVoice; + */ + static final int VOICE_STRUCT_SIZE = OBJECT_STRUCT_SIZE + 16; + static final int VOICE_INTERVAL_OFFSET = OBJECT_STRUCT_SIZE; + static final int VOICE_TIMES_OFFSET = OBJECT_STRUCT_SIZE + 4; + static final int VOICE_SPEAKER_OFFSET = OBJECT_STRUCT_SIZE + 8; + static final int VOICE_VOLUMN_OFFSET = OBJECT_STRUCT_SIZE + 9; + static final int VOICE_TONE_OFFSET = OBJECT_STRUCT_SIZE + 10; + static final int VOICE_SPEED_OFFSET = OBJECT_STRUCT_SIZE + 11; + + /* + //ͼƬ���󣬺������һ������TPixels + typedef struct WINDOW{ + WORD id; + BYTE inMethod; //���뷽ʽ + BYTE outMethod; //������ʽ + BYTE stopMethod; //ͣ����ʽ + BYTE flag; //һЩ���Ʊ�־ + WORD inSpeed; //�����ٶ� + WORD outSpeed; //�����ٶ� + WORD stopSpeed; //ͣ���ٶ�(����Ϊ��˸ʱ����ʾ��˸�ٶ�) + DWORD stoptime; //ͣ��ʱ�� + long stopx; //ͣ��λ�� + DWORD size; //���ݳ��� + }TWindow, *PWindow; + */ + static final int WINDOW_STRUCT_SIZE = 24; //2+1+1+1+1+2+2+2+4+4+4 + static final int WINDOW_IN_METHOD_OFFSET = 2; + static final int WINDOW_OUT_METHOD_OFFSET = 3; + static final int WINDOW_STOP_METHOD_OFFSET = 4; + static final int WINDOW_IN_SPEED_OFFSET = 6; + static final int WINDOW_OUT_SPEED_OFFSET = 8; + static final int WINDOW_STOP_SPEED_OFFSET = 10; + static final int WINDOW_STOP_TIME_OFFSET = 12; + static final int WINDOW_SIZE_OFFSET = 20; + + /* + //ͼƬ���󣬺������һ������TPixels + typedef struct SCHEDULEWINDOW{ + WORD id; + BYTE inMethod; //���뷽ʽ + BYTE outMethod; //������ʽ + BYTE stopMethod; //ͣ����ʽ + BYTE flag; //һЩ���Ʊ�־ + WORD inSpeed; //�����ٶ� + WORD outSpeed; //�����ٶ� + WORD stopSpeed; //ͣ���ٶ�(����Ϊ��˸ʱ����ʾ��˸�ٶ�) + DWORD stoptime; //ͣ��ʱ�� + long stopx; //ͣ��λ�� + DWORD size; //���ݳ��� + TPlaySchedule schedule; //���żƻ� + }TScheduleWindow, *PScheduleWindow; + */ + static final int SCHEDULE_WINDOW_STRUCT_SIZE = WINDOW_STRUCT_SIZE + PLAY_SCHEDULE_SIZE; //2+1+1+1+1+2+2+2+4+4+4+20 + + /* + //�������ݽṹ���壨���󼯰���������� + typedef struct PIXELSET{ + WORD id; //�����ʶ + WORD count; //TPixels������Ŀ + DWORD size; //�����ֽ��� + }TPixelSet, *PPixelSet; + */ + static final int PIXELSET_STRUCT_SIZE = 8; //2+2+4 + static final int PIXELSET_COUNT_OFFSET = 2; + static final int PIXELSET_SIZE_OFFSET = 4; + + /* + //�������ݽṹ���� + typedef struct PIXELS{ + WORD id; //�����ʶ + WORD bits; //ÿ����λ�� + long width; //������ + long height; //����߶� + DWORD size; //�����С + }TPixels, *PPixels; + */ + static final int PIXELS_STRUCT_SIZE = 16; //2+2+4+4+4 + static final int PIXELS_BITS_OFFSET = 2; + static final int PIXELS_WIDTH_OFFSET = 4; + static final int PIXELS_HEIGHT_OFFSET = 8; + static final int PIXELS_SIZE_OFFSET = 12; + + /* + typedef struct PKG_RESPOND{ + TPKG_Header Header; + WORD Command; + WORD Result; + }TPKG_Respond, *PPKG_Respond; + */ + static final int RESPOND_STRUCT_SIZE = 12; + static final int RESPOND_COMMAND_OFFSET = 0; + static final int RESPOND_RESULT_OFFSET = 2; + + /* + typedef struct BOARDPARAM{ + WORD width; + WORD height; + WORD type; + WORD frequency; + DWORD flag; + DWORD uart; //+2+2+2+2+4+4=16 + BYTE mac[ETHER_ADDRESS_LENGTH]; + BYTE ip[IP_ADDRESS_LENGTH]; + BYTE gateMAC[ETHER_ADDRESS_LENGTH]; + BYTE serverIP[IP_ADDRESS_LENGTH]; //+6+4+6+4=36 + BYTE brightness; + BYTE importflag; + BYTE rootcount; + BYTE disconnect_sec; + DWORD rom_size; + long left; + long top; //+4+4+4+4=52 + WORD scan_mode; + WORD server_port; + WORD line_order; + WORD oe_time; + WORD shift_freq; + WORD refresh_freq; //+2+2+2+2+2+2=64; + BYTE GateIP[IP_ADDRESS_LENGTH]; + BYTE ipMask[IP_ADDRESS_LENGTH]; //+4+4=72 + BYTE name[32]; + DWORD ident; + DWORD address; //+32+4+4=112 + DWORD pkp_rx_timeo; + DWORD pkp_tx_timeo; + DWORD pkp_tx_repeat; + BYTE dnsIP[IP_ADDRESS_LENGTH]; + BYTE dnsMAC[ETHER_ADDRESS_LENGTH]; + WORD ReportTime; //+12+4+6+2=136 + //���server_host=0����server_domain��Ч + BYTE serverDomain[32]; + //��ʾ������Կ������������Կ���������ݰ�����ֹ�Ƿ��û�����ʾ���Ϸ�����Ϣ + DWORD key; + DWORD pkp_length; //+32+4+4=176 + //��Ӧ��bin�ļ��� + char bin_name[32]; //+32=208 + ////////////////////////////////////////////////////// + //�����ز��� + BYTE light_sense; + BYTE light_sense_auto; + WORD light_sense_reserved; + WORD light_sense_split_val[8]; + BYTE light_sense_bright_val[8]; //+28=236 + ////////////////////////////////////////////////////// + //˫��ʱ��ͬ���ܿض�IP��ַ + BYTE TimeSyncIP[IP_ADDRESS_LENGTH]; //+4=240 + ////////////////////////////////////////////////////// + //�Զ��������� + BYTE auto_reset_enabled; + BYTE auto_reset_type; + BYTE auto_reset_hour; + BYTE auto_reset_minute; + }TBoardParam, *PBoardParam; + */ + static final int BOARDPARAM_STRUCT_SIZE = 512; + static final int BOARDPARAM_WIDTH_OFFSET = 0; + static final int BOARDPARAM_HEIGHT_OFFSET = 2; + static final int BOARDPARAM_COLORMODE_OFFSET = 4; + static final int BOARDPARAM_IP_OFFSET = 22; + + static int root_seek = -1; + static int root_size = 0; + static int root_count = 0; + static int chapter_seek = -1; + static int chapter_size = 0; + static int chapter_count = 0; + static int region_seek = -1; + static int region_size = 0; + static int region_count = 0; + static int leaf_seek = -1; + static int leaf_size = 0; + static int leaf_count = 0; + static int strings_seek = -1; + static int strings_size = 0; + static int strings_count = 0; + static int windows_seek = -1; + static int windows_size = 0; + static int windows_count = 0; + static int data_seek = 0; + + public static byte[] data_stream; + public static byte[] cmd_stream; + public static byte[] respond_stream; + public static byte[] packet_stream; + public static int packet_size; + + public static int get_boardparam_respond_size = 0; + + public static final int RGB_SPLIT = 64; + + public int fix_serialno=0; + + static private int current_color_type=0; + + public void print_stream(byte[] stream, int size){ + int i; + short x; + String s; + //System.out.print("size="+size+"; "+"data="); + for (i=0; i=0) mac[i]=buffer[index+i]; else mac[i]=(256+buffer[index+i]); + } + return mac[0]+"-"+mac[1]+"-"+mac[2]+"-"+mac[3]+"-"+mac[4]+"-"+mac[5]; + } + + static void intFill(byte[] buffer, int index, int value){ + buffer[index]=lo_of_short(lo_of_int(value)); + buffer[index+1]=hi_of_short(lo_of_int(value)); + buffer[index+2]=lo_of_short(hi_of_int(value)); + buffer[index+3]=hi_of_short(hi_of_int(value)); + } + + static void timeFill(byte[] buffer, int index, int hour, int minute, int second){ + int time; + time=((hour*60+minute)*60+second)*1000; + intFill(buffer, index, time); + } + + static void dateFill(byte[] buffer, int index, int year, int month, int day){ + int date; + int MonthDays[][]={{31,28,31,30,31,30,31,31,30,31,30,31}, {31,29,31,30,31,30,31,31,30,31,30,31}}; + int i,y,m,d; + + y=year-1; + for (m=0,d=year; d>100; d-=100, m++) ; + if ((year&3)==0 && ((m&3)==0 || d!=0)) d=1; else d=0; + + date=day; + for (i=1; i<=month-1; i++) date+=MonthDays[d][i-1]; + date+=y*365+(y>>2)-(y/100)+(y/400); + + intFill(buffer, index, date); + } + + static void timestampFill(byte[] buffer, int index, int year, int month, int day, int hour, int minute, int second){ + timeFill(buffer, index, hour, minute, second); + dateFill(buffer, index+4, year, month, day); + } + + static int asInt(byte[] buffer, int index){ + int value; + int result=0; + if (buffer[index]>=0) value=buffer[index]; else value=(256+buffer[index]); + result+=value; + if (buffer[index+1]>=0) value=buffer[index+1]; else value=(256+buffer[index+1]); + result+=(value<<8); + if (buffer[index+2]>=0) value=buffer[index+2]; else value=(256+buffer[index+2]); + result+=(value<<16); + if (buffer[index+3]>=0) value=buffer[index+3]; else value=(256+buffer[index+3]); + result+=(value<<24); + return result; + } + + static void blockFill(byte[] buffer, int index, int count, byte value){ + int i; + for (i=index; i>8)&0xFF); + opacket[y++]=(byte)PKP_PREFIX; + for (x=0; x0) len=((len+0x3)&(~0x3)); + gb2312=new byte[len]; + blockFill(gb2312, 0, len, (byte)0); + blockCopy(gb2312, 0, s, 0, s.length); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + gb2312=new byte[0]; + } + + seek=data_seek; + size=STRING_STRUCT_SIZE+len; + size=((size+0x3)&(~0x3)); + blockFill(data_stream, seek, size, (byte)0); + shortFill(data_stream, seek, (short)OBJECT_STRING); + byteFill(data_stream, seek+STRING_IN_METHOD_OFFSET, (byte)inmethod); + shortFill(data_stream, seek+STRING_IN_SPEED_OFFSET, (short)inspeed); + byteFill(data_stream, seek+STRING_OUT_METHOD_OFFSET, (byte)outmethod); + shortFill(data_stream, seek+STRING_OUT_SPEED_OFFSET, (short)outspeed); + byteFill(data_stream, seek+STRING_STOP_METHOD_OFFSET, (byte)stopmethod); + shortFill(data_stream, seek+STRING_STOP_SPEED_OFFSET, (short)stopspeed); + intFill(data_stream, seek+STRING_STOP_TIME_OFFSET, stoptime); + intFill(data_stream, seek+STRING_COLOR_OFFSET, color); + shortFill(data_stream, seek+STRING_FONT_SET_OFFSET, (short)fontset); + intFill(data_stream, seek+STRING_SIZE_OFFSET, size); + //stringCopy(data_stream, seek+STRING_STRUCT_SIZE, text, len); + blockCopy(data_stream, seek+STRING_STRUCT_SIZE, gb2312, 0, len); + strings_count++; + shortFill(data_stream, strings_seek+STRINGS_COUNT_OFFSET, (short)strings_count); + strings_size+=size; + intFill(data_stream, strings_seek+OBJECT_SIZE_OFFSET, strings_size); + if (leaf_seek>0) { + leaf_size+=size; + intFill(data_stream, leaf_seek+LEAF_SIZE_OFFSET, leaf_size); + } + if (region_seek>0) { + region_size+=size; + intFill(data_stream, region_seek+REGION_SIZE_OFFSET, region_size); + } + if (chapter_seek>0) { + chapter_size+=size; + intFill(data_stream, chapter_seek+CHAPTER_SIZE_OFFSET, chapter_size); + } + root_size+=size; + intFill(data_stream, root_seek+ROOT_SIZE_OFFSET, root_size); + data_seek=seek+size; + //System.out.println("childstring="+data_seek); + } + + public void AddWindows(int left, int top, int width, int height) { + windows_seek=data_seek; + windows_count=0; + windows_size=WINDOWS_STRUCT_SIZE; + blockFill(data_stream, windows_seek, windows_size, (byte)0); + shortFill(data_stream, windows_seek, (short)OBJECT_WINDOWS); + blockFill(data_stream, windows_seek+OBJECT_TRANSPARENT_OFFSET, 1, (byte)1); + intFill(data_stream, windows_seek+OBJECT_LEFT_OFFSET, left); + intFill(data_stream, windows_seek+OBJECT_TOP_OFFSET, top); + intFill(data_stream, windows_seek+OBJECT_RIGHT_OFFSET, left+width); + intFill(data_stream, windows_seek+OBJECT_BOTTOM_OFFSET, top+height); + shortFill(data_stream, windows_seek+WINDOWS_COUNT_OFFSET, (short)windows_count); + intFill(data_stream, windows_seek+OBJECT_SIZE_OFFSET, windows_size); + if (leaf_seek>0) { + leaf_count++; + shortFill(data_stream, leaf_seek+LEAF_COUNT_OFFSET, (short)leaf_count); + leaf_size+=windows_size; + intFill(data_stream, leaf_seek+LEAF_SIZE_OFFSET, leaf_size); + } + if (region_seek>0) { + region_size+=windows_size; + intFill(data_stream, region_seek+REGION_SIZE_OFFSET, region_size); + } + if (chapter_seek>0) { + chapter_size+=windows_size; + intFill(data_stream, chapter_seek+CHAPTER_SIZE_OFFSET, chapter_size); + } + root_size+=windows_size; + intFill(data_stream, root_seek+ROOT_SIZE_OFFSET, root_size); + data_seek=windows_seek+windows_size; + //System.out.println("windows="+data_seek); + } + + //dib_buffer ����ͼƬRGB���� + //dib_buffer_size ���鳤�� + //dib_width ������ + //dib_height ����߶� + static int AddPixelsRG(int[] dib_buffer, int dib_buffer_size, int dib_width, int dib_height) { + int pixels_seek, pixels_size, pixels_height; + int x, y; + int shift[] = new int[4]; + int shift_value[] = new int[4]; + int shift_mask[] = new int[4]; + int bits_value[] = new int[4]; + int bits_seek, bits_size; + int buffer_seek=0; + int byte_seek=3; + + pixels_height=((dib_height+0xF)&(~0xF)); + bits_size=(pixels_height>>2)*dib_width; + pixels_seek=data_seek; + pixels_size=PIXELS_STRUCT_SIZE+bits_size; + blockFill(data_stream, pixels_seek, pixels_size, (byte)0); + + shortFill(data_stream, pixels_seek, (short)OBJECT_PIXELS); + shortFill(data_stream, pixels_seek+PIXELS_BITS_OFFSET, (short)BITMAP_YELLOW); + intFill(data_stream, pixels_seek+PIXELS_WIDTH_OFFSET, (int)dib_width); + intFill(data_stream, pixels_seek+PIXELS_HEIGHT_OFFSET, (int)pixels_height); + intFill(data_stream, pixels_seek+PIXELS_SIZE_OFFSET, (int)pixels_size); + + bits_seek=pixels_seek+PIXELS_STRUCT_SIZE; + for (x=0; x>8)&0xFF)>RGB_SPLIT) shift_value[byte_seek]|=shift[byte_seek]; + shift[byte_seek]>>=1; + if ((dib_buffer[buffer_seek]&0xFF)>RGB_SPLIT) shift_value[byte_seek]|=shift[byte_seek]; + shift[byte_seek]>>=1; + buffer_seek++; + if (shift_value[byte_seek]>0){ + bits_value[byte_seek]&=(~shift_mask[byte_seek]); + bits_value[byte_seek]|=shift_value[byte_seek]; + } + shift_mask[byte_seek]>>=2; + if (byte_seek==0 && shift[byte_seek]==0){ + data_stream[bits_seek]=(byte)bits_value[0]; + data_stream[bits_seek+1]=(byte)bits_value[1]; + data_stream[bits_seek+2]=(byte)bits_value[2]; + data_stream[bits_seek+3]=(byte)bits_value[3]; + bits_seek+=4; + shift[0]=0x0; shift[1]=0x0; shift[2]=0x0; shift[3]=0x80; + shift_mask[0]=0x0; shift_mask[1]=0x0; shift_mask[2]=0x0; shift_mask[3]=0xC0; + bits_value[0]=0x0; bits_value[1]=0x0; bits_value[2]=0x0; bits_value[3]=0x0; + byte_seek=3; + } + if (shift[byte_seek]==0){ + byte_seek--; + shift[byte_seek]=0x80; + shift_mask[byte_seek]=0xC0; + bits_value[byte_seek]=0; + } + } + if (shift[3]!=0x80){ + data_stream[bits_seek]=(byte)bits_value[0]; + data_stream[bits_seek+1]=(byte)bits_value[1]; + data_stream[bits_seek+2]=(byte)bits_value[2]; + data_stream[bits_seek+3]=(byte)bits_value[3]; + bits_seek+=4; + } + } + + return pixels_size; + } + + //dib_buffer ����ͼƬRGB���� + //dib_buffer_size ���鳤�� + //dib_width ������ + //dib_height ����߶� + static int AddPixelsRGB(int[] dib_buffer, int dib_buffer_size, int dib_width, int dib_height) { + int pixels_seek, pixels_size, pixels_height; + int x, y, i; + int shift[] = new int[4]; + int shift_value_r[] = new int[4]; + int shift_value_g[] = new int[4]; + int shift_value_b[] = new int[4]; + int bits_seek, bits_size; + int buffer_seek=0; + int byte_seek=3; + + pixels_height=((dib_height+0x1F)&(~0x1F)); + bits_size=(pixels_height>>3)*dib_width*3; + pixels_seek=data_seek; + pixels_size=PIXELS_STRUCT_SIZE+bits_size; + blockFill(data_stream, pixels_seek, pixels_size, (byte)0); + + shortFill(data_stream, pixels_seek, (short)OBJECT_PIXELS); + shortFill(data_stream, pixels_seek+PIXELS_BITS_OFFSET, (short)BITMAP_RGB); + intFill(data_stream, pixels_seek+PIXELS_WIDTH_OFFSET, (int)dib_width); + intFill(data_stream, pixels_seek+PIXELS_HEIGHT_OFFSET, (int)pixels_height); + intFill(data_stream, pixels_seek+PIXELS_SIZE_OFFSET, (int)pixels_size); + + bits_seek=pixels_seek+PIXELS_STRUCT_SIZE; + for (x=0; xRGB_SPLIT) { + for (i=0; i<4; i++) shift_value_r[i]|=shift[i]; + } + if (((dib_buffer[buffer_seek]>>8)&0xFF)>RGB_SPLIT) { + for (i=0; i<4; i++) shift_value_g[i]|=shift[i]; + } + if (((dib_buffer[buffer_seek]>>16)&0xFF)>RGB_SPLIT) { + for (i=0; i<4; i++) shift_value_b[i]|=shift[i]; + } + shift[byte_seek]>>=1; + buffer_seek++; + if (byte_seek==0 && shift[byte_seek]==0){ + for (i=0; i<4; i++) data_stream[bits_seek+i]=(byte)shift_value_r[i]; + bits_seek+=4; + for (i=0; i<4; i++) data_stream[bits_seek+i]=(byte)shift_value_g[i]; + bits_seek+=4; + for (i=0; i<4; i++) data_stream[bits_seek+i]=(byte)shift_value_b[i]; + bits_seek+=4; + shift[0]=0x0; shift[1]=0x0; shift[2]=0x0; shift[3]=0x80; + byte_seek=3; + for (i=0; i<4; i++) shift_value_r[i]=0; + for (i=0; i<4; i++) shift_value_g[i]=0; + for (i=0; i<4; i++) shift_value_b[i]=0; + } + if (shift[byte_seek]==0){ + byte_seek--; + shift[byte_seek]=0x80; + } + } + if (shift[3]!=0x80){ + for (i=0; i<4; i++) data_stream[bits_seek+i]=(byte)shift_value_r[i]; + bits_seek+=4; + for (i=0; i<4; i++) data_stream[bits_seek+i]=(byte)shift_value_g[i]; + bits_seek+=4; + for (i=0; i<4; i++) data_stream[bits_seek+i]=(byte)shift_value_b[i]; + bits_seek+=4; + } + } + + return pixels_size; + } + + //dib_buffer ����ͼƬRGB���� + //dib_buffer_size ���鳤�� + //dib_width ������ + //dib_height ����߶� + static int AddPixelsFull(int[] dib_buffer, int dib_buffer_size, int dib_width, int dib_height) { + int pixels_seek, pixels_size, pixels_height; + int x, y, z, i; + int shift[] = new int[4]; + int data_value[] = new int[4]; + int r_value, g_value, b_value; + int bits_seek, bits_size; + int buffer_seek=0; + int byte_seek=3; + + pixels_height=dib_height; + bits_size=pixels_height*dib_width*4; + pixels_seek=data_seek; + pixels_size=PIXELS_STRUCT_SIZE+bits_size; + blockFill(data_stream, pixels_seek, pixels_size, (byte)0); + + shortFill(data_stream, pixels_seek, (short)OBJECT_PIXELS); + shortFill(data_stream, pixels_seek+PIXELS_BITS_OFFSET, (short)BITMAP_RGB); + intFill(data_stream, pixels_seek+PIXELS_WIDTH_OFFSET, (int)dib_width); + intFill(data_stream, pixels_seek+PIXELS_HEIGHT_OFFSET, (int)pixels_height); + intFill(data_stream, pixels_seek+PIXELS_SIZE_OFFSET, (int)pixels_size); + + bits_seek=pixels_seek+PIXELS_STRUCT_SIZE; + for (x=0; x>8)&0xFF); + b_value=((dib_buffer[buffer_seek]>>16)&0xFF); + if (r_value>0 || g_value>0 || b_value>0){ + for (z=0; z<8; z++){ + data_value[byte_seek]<<=1; + if ((r_value & 0x80) > 0) data_value[byte_seek]|=1; + data_value[byte_seek]<<=1; + if ((g_value & 0x80) > 0) data_value[byte_seek]|=1; + data_value[byte_seek]<<=1; + if ((b_value & 0x80) > 0) data_value[byte_seek]|=1; + data_value[byte_seek]<<=1; + r_value<<=1; + g_value<<=1; + b_value<<=1; + shift[byte_seek]>>=4; + if (shift[byte_seek]==0){ + if (byte_seek==0) byte_seek=3; else byte_seek--; + shift[byte_seek]=0x80; + } + } + } + for (i=0; i<4; i++) data_stream[bits_seek+i]=(byte)data_value[i]; + bits_seek+=4; + buffer_seek++; + } + } + + return pixels_size; + } + + static int AddPixels(int[] dib_buffer, int dib_buffer_size, int dib_width, int dib_height) { + switch(current_color_type) { + case COLOR_TYPE_THREE: + return AddPixelsRGB(dib_buffer, dib_buffer_size, dib_width, dib_height); + case COLOR_TYPE_FULL: + return AddPixelsFull(dib_buffer, dib_buffer_size, dib_width, dib_height); + default: + return AddPixelsRG(dib_buffer, dib_buffer_size, dib_width, dib_height); + } + } + + //buffer ����ͼƬRGB���� + //buffer_size ���鳤�� + //width ������ + //height ����߶� + //inmethod ���뷽ʽ���ڴ�java�ļ����Ϸ��ж��� + //outmethod ������ʽ���ڴ�java�ļ����Ϸ��ж��� + //inspeed, outspeed ���������ٶȣ�0��5 + //stopmethod ͣ����ʽ������0 + //stopspeed ͣ���ٶȣ�����0 + public void AddChildWindow(int[] buffer, int buffer_size, int width, int height, int inmethod, int inspeed, int outmethod, int outspeed, int stopmethod, int stopspeed, int stoptime) { + int seek, size; + int pixels_size; + + seek=data_seek; + size=WINDOW_STRUCT_SIZE; + blockFill(data_stream, seek, size, (byte)0); + + shortFill(data_stream, seek, (short)OBJECT_WINDOW); + byteFill(data_stream, seek+WINDOW_IN_METHOD_OFFSET, (byte)inmethod); + shortFill(data_stream, seek+WINDOW_IN_SPEED_OFFSET, (short)inspeed); + byteFill(data_stream, seek+WINDOW_OUT_METHOD_OFFSET, (byte)outmethod); + shortFill(data_stream, seek+WINDOW_OUT_SPEED_OFFSET, (short)outspeed); + byteFill(data_stream, seek+WINDOW_STOP_METHOD_OFFSET, (byte)stopmethod); + shortFill(data_stream, seek+WINDOW_STOP_SPEED_OFFSET, (short)stopspeed); + intFill(data_stream, seek+WINDOW_STOP_TIME_OFFSET, stoptime); + intFill(data_stream, seek+WINDOW_SIZE_OFFSET, size); + + data_seek+=WINDOW_STRUCT_SIZE; + pixels_size=AddPixels(buffer, buffer_size, width, height); + + size+=pixels_size; + intFill(data_stream, seek+WINDOW_SIZE_OFFSET, size); + windows_count++; + shortFill(data_stream, windows_seek+WINDOWS_COUNT_OFFSET, (short)windows_count); + windows_size+=size; + intFill(data_stream, windows_seek+OBJECT_SIZE_OFFSET, windows_size); + if (leaf_seek>0) { + leaf_size+=size; + intFill(data_stream, leaf_seek+LEAF_SIZE_OFFSET, leaf_size); + } + if (region_seek>0) { + region_size+=size; + intFill(data_stream, region_seek+REGION_SIZE_OFFSET, region_size); + } + if (chapter_seek>0) { + chapter_size+=size; + intFill(data_stream, chapter_seek+CHAPTER_SIZE_OFFSET, chapter_size); + } + root_size+=size; + intFill(data_stream, root_seek+ROOT_SIZE_OFFSET, root_size); + data_seek=seek+size; + //System.out.println("childwindow="+data_seek); + } + + //buffer ����ͼƬRGB���� + //buffer_size ���鳤�� + //width ������ + //height ����߶� + //inmethod ���뷽ʽ���ڴ�java�ļ����Ϸ��ж��� + //outmethod ������ʽ���ڴ�java�ļ����Ϸ��ж��� + //inspeed, outspeed ���������ٶȣ�0��5 + //stopmethod ͣ����ʽ������0 + //stopspeed ͣ���ٶȣ�����0 + //kind �ƻ�ģʽ��=0ʼ�ղ��ţ�=1��һ��ÿ�ղ��ţ�=2����ֹʱ�䲥�ţ�=3������ + //week һ�ܶ��壬��kind=1ʱ��Ч����bit0-bit6��ʾ���յ����� + // ����0x1 ��һ0x2 �ܶ�0x4 ����0x8 ����0x10 ����0x20 ����0x30 + // ���ֵ���������ϣ�����ֻ������һ���ܶ���������3�죬��week��ֵ0x2+0x4+0x8���� + public void AddChildScheduleWindow(int[] buffer, int buffer_size, int width, int height, + int inmethod, int inspeed, int outmethod, int outspeed, int stopmethod, int stopspeed, int stoptime, + int kind, int week, + int from_year, int from_month, int from_day, int from_hour, int from_minute, int from_second, + int to_year, int to_month, int to_day, int to_hour, int to_minute, int to_second) { + int seek, size; + int pixels_size; + + seek=data_seek; + size=SCHEDULE_WINDOW_STRUCT_SIZE; + blockFill(data_stream, seek, size, (byte)0); + + shortFill(data_stream, seek, (short)OBJECT_SCHEDULE_WINDOW); + byteFill(data_stream, seek+WINDOW_IN_METHOD_OFFSET, (byte)inmethod); + shortFill(data_stream, seek+WINDOW_IN_SPEED_OFFSET, (short)inspeed); + byteFill(data_stream, seek+WINDOW_OUT_METHOD_OFFSET, (byte)outmethod); + shortFill(data_stream, seek+WINDOW_OUT_SPEED_OFFSET, (short)outspeed); + byteFill(data_stream, seek+WINDOW_STOP_METHOD_OFFSET, (byte)stopmethod); + shortFill(data_stream, seek+WINDOW_STOP_SPEED_OFFSET, (short)stopspeed); + intFill(data_stream, seek+WINDOW_STOP_TIME_OFFSET, stoptime); + intFill(data_stream, seek+WINDOW_SIZE_OFFSET, size); + shortFill(data_stream, seek+WINDOW_STRUCT_SIZE+PLAY_SCHEDULE_KIND_OFFSET, (short)kind); + shortFill(data_stream, seek+WINDOW_STRUCT_SIZE+PLAY_SCHEDULE_WEEK_OFFSET, (short)week); + intFill(data_stream, seek+WINDOW_STRUCT_SIZE+PLAY_SCHEDULE_FROMTIME_OFFSET, SystemTimeToTime(from_hour, from_minute, from_second)); + intFill(data_stream, seek+WINDOW_STRUCT_SIZE+PLAY_SCHEDULE_FROMDATE_OFFSET, SystemTimeToDate(from_year, from_month, from_day)); + intFill(data_stream, seek+WINDOW_STRUCT_SIZE+PLAY_SCHEDULE_TOTIME_OFFSET, SystemTimeToTime(to_hour, to_minute, to_second)); + intFill(data_stream, seek+WINDOW_STRUCT_SIZE+PLAY_SCHEDULE_TODATE_OFFSET, SystemTimeToDate(to_year, to_month, to_day)); + + data_seek+=SCHEDULE_WINDOW_STRUCT_SIZE; + pixels_size=AddPixels(buffer, buffer_size, width, height); + + size+=pixels_size; + intFill(data_stream, seek+WINDOW_SIZE_OFFSET, size); + windows_count++; + shortFill(data_stream, windows_seek+WINDOWS_COUNT_OFFSET, (short)windows_count); + windows_size+=size; + intFill(data_stream, windows_seek+OBJECT_SIZE_OFFSET, windows_size); + if (leaf_seek>0) { + leaf_size+=size; + intFill(data_stream, leaf_seek+LEAF_SIZE_OFFSET, leaf_size); + } + if (region_seek>0) { + region_size+=size; + intFill(data_stream, region_seek+REGION_SIZE_OFFSET, region_size); + } + if (chapter_seek>0) { + chapter_size+=size; + intFill(data_stream, chapter_seek+CHAPTER_SIZE_OFFSET, chapter_size); + } + root_size+=size; + intFill(data_stream, root_seek+ROOT_SIZE_OFFSET, root_size); + data_seek=seek+size; + //System.out.println("childwindow="+data_seek); + } + + static int AddPicturePixels(String filename) { + int pixels_size=0; + BufferedImage bi; + try { + bi = ImageIO.read(new FileInputStream(filename)); + pixels_size=AddPixels(getBufferedImageRGB(bi), bi.getWidth() * bi.getHeight(), bi.getWidth(), bi.getHeight()); + } catch (Exception e) { + e.printStackTrace(); + } + return pixels_size; + } + + //filename ͼƬ�ļ��� + //inmethod ���뷽ʽ���ڴ�java�ļ����Ϸ��ж��� + //outmethod ������ʽ���ڴ�java�ļ����Ϸ��ж��� + //inspeed, outspeed ���������ٶȣ�0��5 + //stopmethod ͣ����ʽ������0 + //stopspeed ͣ���ٶȣ�����0 + public void AddChildPicture(String filename, int inmethod, int inspeed, int outmethod, int outspeed, int stopmethod, int stopspeed, int stoptime) { + int seek, size; + int pixels_size; + + seek=data_seek; + size=WINDOW_STRUCT_SIZE; + blockFill(data_stream, seek, size, (byte)0); + + shortFill(data_stream, seek, (short)OBJECT_WINDOW); + byteFill(data_stream, seek+WINDOW_IN_METHOD_OFFSET, (byte)inmethod); + shortFill(data_stream, seek+WINDOW_IN_SPEED_OFFSET, (short)inspeed); + byteFill(data_stream, seek+WINDOW_OUT_METHOD_OFFSET, (byte)outmethod); + shortFill(data_stream, seek+WINDOW_OUT_SPEED_OFFSET, (short)outspeed); + byteFill(data_stream, seek+WINDOW_STOP_METHOD_OFFSET, (byte)stopmethod); + shortFill(data_stream, seek+WINDOW_STOP_SPEED_OFFSET, (short)stopspeed); + intFill(data_stream, seek+WINDOW_STOP_TIME_OFFSET, stoptime); + intFill(data_stream, seek+WINDOW_SIZE_OFFSET, size); + + data_seek+=WINDOW_STRUCT_SIZE; + pixels_size=AddPicturePixels(filename); + + size+=pixels_size; + intFill(data_stream, seek+WINDOW_SIZE_OFFSET, size); + windows_count++; + shortFill(data_stream, windows_seek+WINDOWS_COUNT_OFFSET, (short)windows_count); + windows_size+=size; + intFill(data_stream, windows_seek+OBJECT_SIZE_OFFSET, windows_size); + if (leaf_seek>0) { + leaf_size+=size; + intFill(data_stream, leaf_seek+LEAF_SIZE_OFFSET, leaf_size); + } + if (region_seek>0) { + region_size+=size; + intFill(data_stream, region_seek+REGION_SIZE_OFFSET, region_size); + } + if (chapter_seek>0) { + chapter_size+=size; + intFill(data_stream, chapter_seek+CHAPTER_SIZE_OFFSET, chapter_size); + } + root_size+=size; + intFill(data_stream, root_seek+ROOT_SIZE_OFFSET, root_size); + data_seek=seek+size; + //System.out.println("childwindow="+data_seek); + } + + static int GetTextPixelsWidth(String text, String fontname, int fontsize, int fontstyle) { + int value=0; + BufferedImage bi; + try { + bi = createImage(text, new Font(fontname, fontstyle, fontsize), Color.BLACK, Color.YELLOW); + value = bi.getWidth(); + } catch (Exception e) { + e.printStackTrace(); + } + return value; + } + + static int GetTextPixelsHeight(String text, String fontname, int fontsize, int fontstyle) { + int value=0; + BufferedImage bi; + try { + bi = createImage(text, new Font(fontname, fontstyle, fontsize), Color.BLACK, Color.YELLOW); + value = bi.getHeight(); + } catch (Exception e) { + e.printStackTrace(); + } + return value; + } + + /* + * ����str,font����ʽ����ͼ�񻺴� + */ + static BufferedImage createImage(String str, Font font, Color bkcolor, Color color) throws Exception { + // ��ȡfont����ʽӦ����str�ϵ��������� + Rectangle2D r = font.getStringBounds(str, new FontRenderContext(AffineTransform.getScaleInstance(1, 1), false, false)); + int unitHeight = (int) Math.floor(r.getHeight());// ��ȡ�����ַ��ĸ߶� + // ��ȡ����str����font��ʽ�Ŀ�����������������+1��֤��Ⱦ�������������ַ�����ΪͼƬ�Ŀ�� + int width = (int) Math.round(r.getWidth()) + 1; + int height = unitHeight + 3;// �ѵ����ַ��ĸ߶�+3��֤�߶Ⱦ����������ַ�����ΪͼƬ�ĸ߶� + // ����ͼƬ + //logger.error(host+"<> ="+width+"="+height); + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); + Graphics g = image.getGraphics(); + g.setColor(bkcolor); + g.fillRect(0, 0, width, height);// ���ú�ɫ�������ͼƬ,Ҳ���DZ��� + g.setColor(color);// �ٻ��ɺ�ɫ + g.setFont(font);// ���û������� + g.drawString(str, 0, font.getSize());// �����ַ��� + g.dispose(); + return image; + } + + static int GetJuhaoOffsetX(int fontsize){ + return -4; + } + + static int GetJuhaoOffsetY(int fontsize){ + return 8; + } + + /* + * ����str,font����ʽ����ͼ�񻺴� + */ + static BufferedImage createImageJuhao(String str, Font font, Color bkcolor, Color color, int fontsize) throws Exception { + // ��ȡfont����ʽӦ����str�ϵ��������� + FontRenderContext rc = new FontRenderContext(AffineTransform.getScaleInstance(1, 1), false, false); + Rectangle2D r = font.getStringBounds(str, rc); + String sTemp; + int unitHeight = (int) Math.floor(r.getHeight());// ��ȡ�����ַ��ĸ߶� + // ��ȡ����str����font��ʽ�Ŀ�����������������+1��֤��Ⱦ�������������ַ�����ΪͼƬ�Ŀ�� + int width = (int) Math.round(r.getWidth()) + 1; + int height = unitHeight + 3;// �ѵ����ַ��ĸ߶�+3��֤�߶Ⱦ����������ַ�����ΪͼƬ�ĸ߶� + int[] iWidths; + String[] sItems; + int i, k, x, y; + + x = 0; + sTemp = str; + k = sTemp.indexOf("��"); + while (k >= 0){ + x+=2; + sTemp = sTemp.substring(k+1); + k = sTemp.indexOf("��"); + } + if (!sTemp.isEmpty()) { + x++; + } + sItems = new String[x]; + iWidths = new int[x]; + + x = 0; + sTemp = str; + k = sTemp.indexOf("��"); + while (k >= 0){ + sItems[x++] = sTemp.substring(0, k); + sItems[x++] = "��"; + sTemp = sTemp.substring(k+1); + k = sTemp.indexOf("��"); + } + if (!sTemp.isEmpty()) { + sItems[x++] = sTemp; + } + + k = x; + width = 0; + for (i=0; i> ="+width+"="+height); + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); + Graphics g = image.getGraphics(); + g.setColor(bkcolor); + g.fillRect(0, 0, width, height);// ���ú�ɫ�������ͼƬ,Ҳ���DZ��� + g.setColor(color);// �ٻ��ɺ�ɫ + g.setFont(font);// ���û������� + + x = 0; + y = font.getSize(); + for (i=0; iwidth) width=cwidth; + strlist.add(szLine); + widthlist.add(cwidth); + cwidth=0; + height+=cy; + szLine=""; + ch_return=true; + i++; + } + else if (szChar.compareTo("\n")==0) + { + if (!ch_return) + { + r=font.getStringBounds("V", new FontRenderContext(AffineTransform.getScaleInstance(1, 1), false, false)); + // ��ȡ�����ַ��ĸ߶ȣ� �ѵ����ַ��ĸ߶�+3��֤�߶Ⱦ����������ַ�����ΪͼƬ�ĸ߶� + cy = (int) Math.floor(r.getHeight()) + 3; + if (cwidth>width) width=cwidth; + strlist.add(szLine); + widthlist.add(cwidth); + cwidth=0; + height+=cy; + szLine=""; + } + ch_return=false; + i++; + } + else + { + r=font.getStringBounds(szChar, new FontRenderContext(AffineTransform.getScaleInstance(1, 1), false, false)); + // ��ȡ����str����font��ʽ�Ŀ�����������������+1��֤��Ⱦ�������������ַ�����ΪͼƬ�Ŀ�� + cx = (int) Math.round(r.getWidth()) + 1; + // ��ȡ�����ַ��ĸ߶ȣ� �ѵ����ַ��ĸ߶�+3��֤�߶Ⱦ����������ַ�����ΪͼƬ�ĸ߶� + cy = (int) Math.floor(r.getHeight()) + 3; + if (cwidth>0 && cwidth+cx>matrixwidth){ + if (cwidth>width) width=cwidth; + strlist.add(szLine); + widthlist.add(cwidth); + cwidth=cx; + height+=cy; + szLine=szChar; + } + else{ + cwidth+=cx; + szLine=szLine+szChar; + } + ch_return=false; + i++; + } + //System.out.print(ch); + } + if (cwidth>0){ + if (cwidth>width) width=cwidth; + strlist.add(szLine); + widthlist.add(cwidth); + height+=cy; + } + if (width==0 || height==0){ + width=10; height=10; + } + // ����ͼƬ + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR); + Graphics g = image.getGraphics(); + g.setColor(bkcolor); + g.fillRect(0, 0, width, height);// ���ú�ɫ�������ͼƬ,Ҳ���DZ��� + g.setColor(color);// �ٻ��ɺ�ɫ + g.setFont(font);// ���û������� + y=font.getSize(); + for (i=0; i> 16; + green = (pix & 0x00ff00) >> 8; + blue = (pix & 0xff); + imageRGB[i*height+j] = (int) blue << 16 | (int) green << 8 | (int) red; + } + } + + return imageRGB; + } + + static int AddTextPixels(String text, String fontname, int fontsize, Color bkcolor, Color fontcolor, int fontstyle, int halign, boolean wordwrap, int matrixwidth) { + int pixels_size=0; + BufferedImage bi; + try { + //�˴�������쳣������exception����ɵ�������û������ϣ���ĿУ��ͻ�ʧ�� + //���ڴ˴���ӡ��־����ʾ��������в��� + //logger.error(host+"<> ="+text+"="+fontname+"="+fontstyle+"="+fontsize+"="+bkcolor+"="+fontcolor+"="+halign+"="+wordwrap+"="+matrixwidth); + bi = createImageEx(text, new Font(fontname, fontstyle, fontsize), bkcolor, fontcolor, halign, wordwrap, matrixwidth); + //logger.error(host+"<> ="+bi.getWidth()+"="+bi.getHeight()); + pixels_size=AddPixels(getBufferedImageRGB(bi), bi.getWidth() * bi.getHeight(), bi.getWidth(), bi.getHeight()); + } catch (Exception e) { + //logger.error(host+"<> ="+e.getMessage()); + e.printStackTrace(); + } + return pixels_size; + } + + static int AddTextPixelsJuhao(String text, String fontname, int fontsize, Color bkcolor, Color fontcolor, int fontstyle, int halign, boolean wordwrap, int matrixwidth) { + int pixels_size=0; + BufferedImage bi; + try { + //�˴�������쳣������exception����ɵ�������û������ϣ���ĿУ��ͻ�ʧ�� + //���ڴ˴���ӡ��־����ʾ��������в��� + //logger.error(host+"<> ="+text+"="+fontname+"="+fontstyle+"="+fontsize+"="+bkcolor+"="+fontcolor+"="+halign+"="+wordwrap+"="+matrixwidth); + bi = createImageJuhao(text, new Font(fontname, fontstyle, fontsize), bkcolor, fontcolor, fontsize); + //logger.error(host+"<> ="+bi.getWidth()+"="+bi.getHeight()); + pixels_size=AddPixels(getBufferedImageRGB(bi), bi.getWidth() * bi.getHeight(), bi.getWidth(), bi.getHeight()); + } catch (Exception e) { + //logger.error(host+"<> ="+e.getMessage()); + e.printStackTrace(); + } + return pixels_size; + } + + //buffer ����ͼƬRGB���� + //buffer_size ���鳤�� + //width ������ + //height ����߶� + //inmethod ���뷽ʽ���ڴ�java�ļ����Ϸ��ж��� + //outmethod ������ʽ���ڴ�java�ļ����Ϸ��ж��� + //inspeed, outspeed ���������ٶȣ�0��5 + //stopmethod ͣ����ʽ������0 + //stopspeed ͣ���ٶȣ�����0 + public void AddChildText(String text, String fontname, int fontsize, Color bkcolor, Color fontcolor, int fontstyle, int halign, boolean wordwrap, int inmethod, int inspeed, int outmethod, int outspeed, int stopmethod, int stopspeed, int stoptime) { + int seek, size; + int pixels_size; + int matrix_width; + + seek=data_seek; + size=WINDOW_STRUCT_SIZE; + blockFill(data_stream, seek, size, (byte)0); + + shortFill(data_stream, seek, (short)OBJECT_WINDOW); + byteFill(data_stream, seek+WINDOW_IN_METHOD_OFFSET, (byte)inmethod); + shortFill(data_stream, seek+WINDOW_IN_SPEED_OFFSET, (short)inspeed); + byteFill(data_stream, seek+WINDOW_OUT_METHOD_OFFSET, (byte)outmethod); + shortFill(data_stream, seek+WINDOW_OUT_SPEED_OFFSET, (short)outspeed); + byteFill(data_stream, seek+WINDOW_STOP_METHOD_OFFSET, (byte)stopmethod); + shortFill(data_stream, seek+WINDOW_STOP_SPEED_OFFSET, (short)stopspeed); + intFill(data_stream, seek+WINDOW_STOP_TIME_OFFSET, stoptime); + intFill(data_stream, seek+WINDOW_SIZE_OFFSET, size); + + data_seek+=WINDOW_STRUCT_SIZE; + matrix_width=asInt(data_stream, windows_seek+OBJECT_RIGHT_OFFSET)-asInt(data_stream, windows_seek+OBJECT_LEFT_OFFSET); + pixels_size=AddTextPixels(text, fontname, fontsize, bkcolor, fontcolor, fontstyle, halign, wordwrap, matrix_width); + + size+=pixels_size; + intFill(data_stream, seek+WINDOW_SIZE_OFFSET, size); + windows_count++; + shortFill(data_stream, windows_seek+WINDOWS_COUNT_OFFSET, (short)windows_count); + windows_size+=size; + intFill(data_stream, windows_seek+OBJECT_SIZE_OFFSET, windows_size); + if (leaf_seek>0) { + leaf_size+=size; + intFill(data_stream, leaf_seek+LEAF_SIZE_OFFSET, leaf_size); + } + if (region_seek>0) { + region_size+=size; + intFill(data_stream, region_seek+REGION_SIZE_OFFSET, region_size); + } + if (chapter_seek>0) { + chapter_size+=size; + intFill(data_stream, chapter_seek+CHAPTER_SIZE_OFFSET, chapter_size); + } + root_size+=size; + intFill(data_stream, root_seek+ROOT_SIZE_OFFSET, root_size); + data_seek=seek+size; + //System.out.println("childwindow="+data_seek); + } + + //buffer ����ͼƬRGB���� + //buffer_size ���鳤�� + //width ������ + //height ����߶� + //inmethod ���뷽ʽ���ڴ�java�ļ����Ϸ��ж��� + //outmethod ������ʽ���ڴ�java�ļ����Ϸ��ж��� + //inspeed, outspeed ���������ٶȣ�0��5 + //stopmethod ͣ����ʽ������0 + //stopspeed ͣ���ٶȣ�����0 + public void AddChildTextJuhao(String text, String fontname, int fontsize, Color bkcolor, Color fontcolor, int fontstyle, int halign, boolean wordwrap, int inmethod, int inspeed, int outmethod, int outspeed, int stopmethod, int stopspeed, int stoptime) { + int seek, size; + int pixels_size; + int matrix_width; + + seek=data_seek; + size=WINDOW_STRUCT_SIZE; + blockFill(data_stream, seek, size, (byte)0); + + shortFill(data_stream, seek, (short)OBJECT_WINDOW); + byteFill(data_stream, seek+WINDOW_IN_METHOD_OFFSET, (byte)inmethod); + shortFill(data_stream, seek+WINDOW_IN_SPEED_OFFSET, (short)inspeed); + byteFill(data_stream, seek+WINDOW_OUT_METHOD_OFFSET, (byte)outmethod); + shortFill(data_stream, seek+WINDOW_OUT_SPEED_OFFSET, (short)outspeed); + byteFill(data_stream, seek+WINDOW_STOP_METHOD_OFFSET, (byte)stopmethod); + shortFill(data_stream, seek+WINDOW_STOP_SPEED_OFFSET, (short)stopspeed); + intFill(data_stream, seek+WINDOW_STOP_TIME_OFFSET, stoptime); + intFill(data_stream, seek+WINDOW_SIZE_OFFSET, size); + + data_seek+=WINDOW_STRUCT_SIZE; + matrix_width=asInt(data_stream, windows_seek+OBJECT_RIGHT_OFFSET)-asInt(data_stream, windows_seek+OBJECT_LEFT_OFFSET); + pixels_size=AddTextPixelsJuhao(text, fontname, fontsize, bkcolor, fontcolor, fontstyle, halign, wordwrap, matrix_width); + + size+=pixels_size; + intFill(data_stream, seek+WINDOW_SIZE_OFFSET, size); + windows_count++; + shortFill(data_stream, windows_seek+WINDOWS_COUNT_OFFSET, (short)windows_count); + windows_size+=size; + intFill(data_stream, windows_seek+OBJECT_SIZE_OFFSET, windows_size); + if (leaf_seek>0) { + leaf_size+=size; + intFill(data_stream, leaf_seek+LEAF_SIZE_OFFSET, leaf_size); + } + if (region_seek>0) { + region_size+=size; + intFill(data_stream, region_seek+REGION_SIZE_OFFSET, region_size); + } + if (chapter_seek>0) { + chapter_size+=size; + intFill(data_stream, chapter_seek+CHAPTER_SIZE_OFFSET, chapter_size); + } + root_size+=size; + intFill(data_stream, root_seek+ROOT_SIZE_OFFSET, root_size); + data_seek=seek+size; + //System.out.println("childwindow="+data_seek); + } + + //buffer ����ͼƬRGB���� + //buffer_size ���鳤�� + //width ������ + //height ����߶� + //inmethod ���뷽ʽ���ڴ�java�ļ����Ϸ��ж��� + //outmethod ������ʽ���ڴ�java�ļ����Ϸ��ж��� + //inspeed, outspeed ���������ٶȣ�0��5 + //stopmethod ͣ����ʽ������0 + //stopspeed ͣ���ٶȣ�����0 + public void AddChildScheduleText(String text, String fontname, int fontsize, Color bkcolor, Color fontcolor, int fontstyle, int halign, boolean wordwrap, + int inmethod, int inspeed, int outmethod, int outspeed, int stopmethod, int stopspeed, int stoptime, + int kind, int week, + int from_year, int from_month, int from_day, int from_hour, int from_minute, int from_second, + int to_year, int to_month, int to_day, int to_hour, int to_minute, int to_second) { + int seek, size; + int pixels_size; + int matrix_width; + + seek=data_seek; + size=SCHEDULE_WINDOW_STRUCT_SIZE; + blockFill(data_stream, seek, size, (byte)0); + + shortFill(data_stream, seek, (short)OBJECT_SCHEDULE_WINDOW); + byteFill(data_stream, seek+WINDOW_IN_METHOD_OFFSET, (byte)inmethod); + shortFill(data_stream, seek+WINDOW_IN_SPEED_OFFSET, (short)inspeed); + byteFill(data_stream, seek+WINDOW_OUT_METHOD_OFFSET, (byte)outmethod); + shortFill(data_stream, seek+WINDOW_OUT_SPEED_OFFSET, (short)outspeed); + byteFill(data_stream, seek+WINDOW_STOP_METHOD_OFFSET, (byte)stopmethod); + shortFill(data_stream, seek+WINDOW_STOP_SPEED_OFFSET, (short)stopspeed); + intFill(data_stream, seek+WINDOW_STOP_TIME_OFFSET, stoptime); + intFill(data_stream, seek+WINDOW_SIZE_OFFSET, size); + shortFill(data_stream, seek+WINDOW_STRUCT_SIZE+PLAY_SCHEDULE_KIND_OFFSET, (short)kind); + shortFill(data_stream, seek+WINDOW_STRUCT_SIZE+PLAY_SCHEDULE_WEEK_OFFSET, (short)week); + intFill(data_stream, seek+WINDOW_STRUCT_SIZE+PLAY_SCHEDULE_FROMTIME_OFFSET, SystemTimeToTime(from_hour, from_minute, from_second)); + intFill(data_stream, seek+WINDOW_STRUCT_SIZE+PLAY_SCHEDULE_FROMDATE_OFFSET, SystemTimeToDate(from_year, from_month, from_day)); + intFill(data_stream, seek+WINDOW_STRUCT_SIZE+PLAY_SCHEDULE_TOTIME_OFFSET, SystemTimeToTime(to_hour, to_minute, to_second)); + intFill(data_stream, seek+WINDOW_STRUCT_SIZE+PLAY_SCHEDULE_TODATE_OFFSET, SystemTimeToDate(to_year, to_month, to_day)); + + data_seek+=SCHEDULE_WINDOW_STRUCT_SIZE; + matrix_width=asInt(data_stream, windows_seek+OBJECT_RIGHT_OFFSET)-asInt(data_stream, windows_seek+OBJECT_LEFT_OFFSET); + pixels_size=AddTextPixels(text, fontname, fontsize, bkcolor, fontcolor, fontstyle, halign, wordwrap, matrix_width); + + size+=pixels_size; + intFill(data_stream, seek+WINDOW_SIZE_OFFSET, size); + windows_count++; + shortFill(data_stream, windows_seek+WINDOWS_COUNT_OFFSET, (short)windows_count); + windows_size+=size; + intFill(data_stream, windows_seek+OBJECT_SIZE_OFFSET, windows_size); + if (leaf_seek>0) { + leaf_size+=size; + intFill(data_stream, leaf_seek+LEAF_SIZE_OFFSET, leaf_size); + } + if (region_seek>0) { + region_size+=size; + intFill(data_stream, region_seek+REGION_SIZE_OFFSET, region_size); + } + if (chapter_seek>0) { + chapter_size+=size; + intFill(data_stream, chapter_seek+CHAPTER_SIZE_OFFSET, chapter_size); + } + root_size+=size; + intFill(data_stream, root_seek+ROOT_SIZE_OFFSET, root_size); + data_seek=seek+size; + //System.out.println("childwindow="+data_seek); + } + + //����ʱ����ʾ��ʽ������ + private void SDClockFormat(byte[] stream, int index, String format){ + if (format=="#y"){ + stream[index]=DF_YEAR; + stream[index+1]=0; + }else if (format=="#m"){ + stream[index]=DF_MONTH; + stream[index+1]=0; + }else if (format=="#w"){ + stream[index]=DF_WEEK; + stream[index+1]=0; + }else if (format=="#d"){ + stream[index]=DF_DAY; + stream[index+1]=0; + }else if (format=="#h"){ + stream[index]=DF_HOUR; + stream[index+1]=0; + }else if (format=="#n"){ + stream[index]=DF_MINUTE; + stream[index+1]=0; + }else if (format=="#s"){ + stream[index]=DF_SECOND; + stream[index+1]=0; + }else if (format=="��"){ + stream[index]=DF_USER; + stream[index+1]=0; + }else if (format=="��"){ + stream[index]=DF_USER; + stream[index+1]=1; + }else if (format=="��"){ + stream[index]=DF_USER; + stream[index+1]=2; + }else if (format=="ʱ"){ + stream[index]=DF_USER; + stream[index+1]=3; + }else if (format=="��"){ + stream[index]=DF_USER; + stream[index+1]=4; + }else if (format=="��"){ + stream[index]=DF_USER; + stream[index+1]=5; + }else if (format=="��"){ + stream[index]=DF_USER; + stream[index+1]=6; + }else if (format=="��"){ + stream[index]=DF_USER; + stream[index+1]=7; + }else if (format=="-"){ + stream[index]=DF_USER; + stream[index+1]=8; + }else if (format==":"){ + stream[index]=DF_USER; + stream[index+1]=9; + }else if (format==" "){ + stream[index]=DF_USER; + stream[index+1]=10; + } + } + + public void AddStringDateTime(int left, int top, int width, int height, int color, int fontset, String[] formats, int formats_count) { + int seek, size; + int i; + seek=data_seek; + size=SDCLOCK_STRUCT_SIZE; + blockFill(data_stream, seek, size, (byte)0); + shortFill(data_stream, seek, (short)OBJECT_STRING_DCLOCK); + blockFill(data_stream, seek+OBJECT_TRANSPARENT_OFFSET, 1, (byte)1); + intFill(data_stream, seek+OBJECT_LEFT_OFFSET, left); + intFill(data_stream, seek+OBJECT_TOP_OFFSET, top); + intFill(data_stream, seek+OBJECT_RIGHT_OFFSET, left+width); + intFill(data_stream, seek+OBJECT_BOTTOM_OFFSET, top+height); + for (i=0; i0) { + leaf_count++; + shortFill(data_stream, leaf_seek+LEAF_COUNT_OFFSET, (short)leaf_count); + leaf_size+=size; + intFill(data_stream, leaf_seek+LEAF_SIZE_OFFSET, leaf_size); + } + if (region_seek>0) { + region_size+=size; + intFill(data_stream, region_seek+REGION_SIZE_OFFSET, region_size); + } + if (chapter_seek>0) { + chapter_size+=size; + intFill(data_stream, chapter_seek+CHAPTER_SIZE_OFFSET, chapter_size); + } + root_size+=size; + intFill(data_stream, root_seek+ROOT_SIZE_OFFSET, root_size); + data_seek=seek+size; + //System.out.println("strings="+data_seek); + } + + //����������֣���Ҫ���ƿ������ֿ� + //left,top,width,height: ���Ͽ�� + //text: ���� + //inmethod: ���뷽ʽ + //inspeed: �����ٶ� + //outmethod: ������ʽ + //outspeed: �����ٶ� + //stopmethod: ͣ����ʽ + //stopspeed: ͣ���ٶ� + //stoptime: ͣ��ʱ�䣨���룩 + public void AddString(int left, int top, int width, int height, String text, int inmethod, int inspeed, int outmethod, int outspeed, int stopmethod, int stopspeed, int stoptime, int color, int fontset) { + AddStrings(left, top, width, height); + AddChildString(text, inmethod, inspeed, outmethod, outspeed, stopmethod, stopspeed, stoptime, color, fontset); + } + + //��ӵ���ͼƬ + //left,top,width,height: ���Ͽ�� + //buffer: ͼƬ�������� + //buffer_size: ���ݳ��� + //inmethod: ���뷽ʽ + //inspeed: �����ٶ� + //outmethod: ������ʽ + //outspeed: �����ٶ� + //stopmethod: ͣ����ʽ + //stopspeed: ͣ���ٶ� + //stoptime: ͣ��ʱ�䣨���룩 + public void AddWindow(int left, int top, int width, int height, int[] buffer, int buffer_size, int dib_width, int dib_height, int inmethod, int inspeed, int outmethod, int outspeed, int stopmethod, int stopspeed, int stoptime) { + AddWindows(left, top, width, height); + AddChildWindow(buffer, buffer_size, dib_width, dib_height, inmethod, inspeed, outmethod, outspeed, stopmethod, stopspeed, stoptime); + } + + //���ͼƬ�ļ� + //left,top,width,height: ���Ͽ�� + //filename: ͼƬ�ļ��� + //inmethod: ���뷽ʽ + //inspeed: �����ٶ� + //outmethod: ������ʽ + //outspeed: �����ٶ� + //stopmethod: ͣ����ʽ + //stopspeed: ͣ���ٶ� + //stoptime: ͣ��ʱ�䣨���룩 + public void AddPicture(int left, int top, int width, int height, String filename, int inmethod, int inspeed, int outmethod, int outspeed, int stopmethod, int stopspeed, int stoptime) { + AddWindows(left, top, width, height); + AddChildPicture(filename, inmethod, inspeed, outmethod, outspeed, stopmethod, stopspeed, stoptime); + } + + //��ӵ������� + //left,top,width,height: ���Ͽ�� + //text: ���� + //fontname: �������� + //fontsize: �����С + //bkcolor: ����ɫ����Ч����0�� + //fontcolor: ������ɫ + //fontstyle: ��������Ч����0�� + //inmethod: ���뷽ʽ + //inspeed: �����ٶ� + //outmethod: ������ʽ + //outspeed: �����ٶ� + //stopmethod: ͣ����ʽ + //stopspeed: ͣ���ٶ� + //stoptime: ͣ��ʱ�䣨���룩 + public void AddText(int left, int top, int width, int height, String text, String fontname, int fontsize, Color bkcolor, Color fontcolor, int fontstyle, int halign, boolean wordwrap, int inmethod, int inspeed, int outmethod, int outspeed, int stopmethod, int stopspeed, int stoptime) { + AddWindows(left, top, width, height); + AddChildText(text, fontname, fontsize, bkcolor, fontcolor, fontstyle, halign, wordwrap, inmethod, inspeed, outmethod, outspeed, stopmethod, stopspeed, stoptime); + } + + //��ӵ������� + //left,top,width,height: ���Ͽ�� + //text: ���� + //halign: ������뷽ʽ 0����1���У�2���� + //valign: ������뷽ʽ 0���ϣ�1���У�2���� + //fontname: �������� + //fontsize: �����С + //bkcolor: ����ɫ����Ч����0�� + //fontcolor: ������ɫ + //fontstyle: ��������Ч����0�� + //inmethod: ���뷽ʽ + //inspeed: �����ٶ� + //outmethod: ������ʽ + //outspeed: �����ٶ� + //stopmethod: ͣ����ʽ + //stopspeed: ͣ���ٶ� + //stoptime: ͣ��ʱ�䣨���룩 + public void AddTextEx(int left, int top, int width, int height, String text, int halign, int valign, String fontname, int fontsize, Color bkcolor, Color fontcolor, int fontstyle, int inmethod, int inspeed, int outmethod, int outspeed, int stopmethod, int stopspeed, int stoptime) { + int textwidth, textheight; + AddWindows(left, top, width, height); + AddChildText(text, fontname, fontsize, bkcolor, fontcolor, fontstyle, halign, false, inmethod, inspeed, outmethod, outspeed, stopmethod, stopspeed, stoptime); + + textwidth=GetTextPixelsWidth(text, fontname, fontsize, fontstyle); + if (textwidth>1)); + break; + case ALIGN_RIGHT: + intFill(data_stream, windows_seek+OBJECT_LEFT_OFFSET, left+width-textwidth); + break; + } + } + textheight=GetTextPixelsHeight(text, fontname, fontsize, fontstyle); + if (textheight>1)); + break; + case ALIGN_BOTTOM: + intFill(data_stream, windows_seek+OBJECT_TOP_OFFSET, top+height-textheight); + break; + } + } + } + + //��ӵ������� + //left,top,width,height: ���Ͽ�� + //text: ���� + //fontname: �������� + //fontsize: �����С + //bkcolor: ����ɫ����Ч����0�� + //fontcolor: ������ɫ + //fontstyle: ��������Ч����0�� + //inmethod: ���뷽ʽ + //inspeed: �����ٶ� + //outmethod: ������ʽ + //outspeed: �����ٶ� + //stopmethod: ͣ����ʽ + //stopspeed: ͣ���ٶ� + //stoptime: ͣ��ʱ�䣨���룩 + public void AddTextJuhao(int left, int top, int width, int height, String text, String fontname, int fontsize, Color bkcolor, Color fontcolor, int fontstyle, int halign, boolean wordwrap, int inmethod, int inspeed, int outmethod, int outspeed, int stopmethod, int stopspeed, int stoptime) { + AddWindows(left, top, width, height); + AddChildTextJuhao(text, fontname, fontsize, bkcolor, fontcolor, fontstyle, halign, wordwrap, inmethod, inspeed, outmethod, outspeed, stopmethod, stopspeed, stoptime); + } + + //����ʱ����ʾ��ʽ������ + private int DClockFormat(byte[] stream, int index, String format){ + if (format=="#y"){ + stream[index]=DF_USER; + stream[index+1]=2; + stream[index+2]=DF_USER; + stream[index+3]=0; + stream[index+4]=DF_YEAR; + stream[index+5]=0; + stream[index+6]=DF_YEAR; + stream[index+7]=1; + return 8; + }else if (format=="#m"){ + stream[index]=DF_MONTH; + stream[index+1]=0; + stream[index+2]=DF_MONTH; + stream[index+3]=1; + return 4; + }else if (format=="#w"){ + stream[index]=DF_WEEK; + stream[index+1]=10; + return 2; + }else if (format=="#d"){ + stream[index]=DF_DAY; + stream[index+1]=0; + stream[index+2]=DF_DAY; + stream[index+3]=1; + return 4; + }else if (format=="#h"){ + stream[index]=DF_HOUR; + stream[index+1]=0; + stream[index+2]=DF_HOUR; + stream[index+3]=1; + return 4; + }else if (format=="#n"){ + stream[index]=DF_MINUTE; + stream[index+1]=0; + stream[index+2]=DF_MINUTE; + stream[index+3]=1; + return 4; + }else if (format=="#s"){ + stream[index]=DF_SECOND; + stream[index+1]=0; + stream[index+2]=DF_SECOND; + stream[index+3]=1; + return 4; + }else if (format=="��"){ + stream[index]=DF_USER; + stream[index+1]=17; + return 2; + }else if (format=="��"){ + stream[index]=DF_USER; + stream[index+1]=18; + return 2; + }else if (format=="��"){ + stream[index]=DF_USER; + stream[index+1]=19; + return 2; + }else if (format=="ʱ"){ + stream[index]=DF_USER; + stream[index+1]=20; + return 2; + }else if (format=="��"){ + stream[index]=DF_USER; + stream[index+1]=21; + return 2; + }else if (format=="��"){ + stream[index]=DF_USER; + stream[index+1]=22; + return 2; + }else if (format=="����"){ + stream[index]=DF_USER; + stream[index+1]=23; + return 2; + }else if (format=="-"){ + stream[index]=DF_USER; + stream[index+1]=24; + return 2; + }else if (format==":"){ + stream[index]=DF_USER; + stream[index+1]=25; + return 2; + }else if (format==" "){ + stream[index]=DF_USER; + stream[index+1]=26; + return 2; + } + return 0; + } + + public void AddDateTime(int left, int top, int width, int height, String[] formats, int formats_count, String fontname, int fontsize, Color bkcolor, Color fontcolor, int fontstyle) + { + int seek, format_seek, size; + int i; + int pixels_size; + int pixelset_size; + + seek=data_seek; + size=DCLOCK_STRUCT_SIZE; + blockFill(data_stream, seek, size, (byte)0); + shortFill(data_stream, seek, (short)OBJECT_DCLOCK); + blockFill(data_stream, seek+OBJECT_TRANSPARENT_OFFSET, 1, (byte)1); + intFill(data_stream, seek+OBJECT_LEFT_OFFSET, left); + intFill(data_stream, seek+OBJECT_TOP_OFFSET, top); + intFill(data_stream, seek+OBJECT_RIGHT_OFFSET, left+width); + intFill(data_stream, seek+OBJECT_BOTTOM_OFFSET, top+height); + format_seek=OBJECT_STRUCT_SIZE+DCLOCK_FORMAT_OFFSET; + for (i=0; i0) { + leaf_count++; + shortFill(data_stream, leaf_seek+LEAF_COUNT_OFFSET, (short)leaf_count); + leaf_size+=size; + intFill(data_stream, leaf_seek+LEAF_SIZE_OFFSET, leaf_size); + } + if (region_seek>0) { + region_size+=size; + intFill(data_stream, region_seek+REGION_SIZE_OFFSET, region_size); + } + if (chapter_seek>0) { + chapter_size+=size; + intFill(data_stream, chapter_seek+CHAPTER_SIZE_OFFSET, chapter_size); + } + root_size+=size; + intFill(data_stream, root_seek+ROOT_SIZE_OFFSET, root_size); + data_seek=seek+size; + } + + //interval ������������ʱ���� + //times �ظ����� =0ʱ������ѭ���ظ����� + //speeker �ʶ��� 0-5 + //volumn ���� 0-9 + //speed ���� 0-9 + //tone ��� 0-9 + public void AddVoice(String text, int interval, int times, int speaker, int volumn, int speed, int tone) + { + int seek, size; + int len=0; + byte[] gb2312; + try { + byte[] s=text.getBytes("GB2312"); + print_stream(s, s.length); + len=s.length+1; + if ((len&0x3)>0) len=((len+0x3)&(~0x3)); + gb2312=new byte[len]; + blockFill(gb2312, 0, len, (byte)0); + blockCopy(gb2312, 0, s, 0, s.length); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + gb2312=new byte[0]; + } + seek=data_seek; + size=VOICE_STRUCT_SIZE+len; + size=((size+0x3)&(~0x3)); + blockFill(data_stream, seek, size, (byte)0); + shortFill(data_stream, seek, (short)OBJECT_VOICE); + intFill(data_stream, seek+OBJECT_SIZE_OFFSET, size); + intFill(data_stream, seek+VOICE_INTERVAL_OFFSET, interval); + intFill(data_stream, seek+VOICE_TIMES_OFFSET, times); + byteFill(data_stream, seek+VOICE_SPEAKER_OFFSET, (byte)speaker); + byteFill(data_stream, seek+VOICE_VOLUMN_OFFSET, (byte)volumn); + byteFill(data_stream, seek+VOICE_SPEED_OFFSET, (byte)speed); + byteFill(data_stream, seek+VOICE_TONE_OFFSET, (byte)tone); + blockCopy(data_stream, seek+VOICE_STRUCT_SIZE, gb2312, 0, len); + + if (leaf_seek>0) { + leaf_count++; + shortFill(data_stream, leaf_seek+LEAF_COUNT_OFFSET, (short)leaf_count); + leaf_size+=size; + intFill(data_stream, leaf_seek+LEAF_SIZE_OFFSET, leaf_size); + } + if (region_seek>0) { + region_size+=size; + intFill(data_stream, region_seek+REGION_SIZE_OFFSET, region_size); + } + if (chapter_seek>0) { + chapter_size+=size; + intFill(data_stream, chapter_seek+CHAPTER_SIZE_OFFSET, chapter_size); + } + root_size+=strings_size; + intFill(data_stream, root_seek+ROOT_SIZE_OFFSET, root_size); + data_seek=seek+size; + //System.out.println("strings="+data_seek); + } + + // ��ʼ�� + public int pkg_begin(byte[] packet, int addr) { + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_BEGIN); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE); + } + + // ������ + public int pkg_end(byte[] packet, int addr, int serial_no) { + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_END); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + intFill(cmd_stream, PKG_HEADER_SERIALNO_OFFSET, serial_no); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE); + } + + // ���ݰ� + public int pkg_data(byte[] packet, int addr, int serial_no, int pkg_length) { + int size; + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_DATA); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + intFill(cmd_stream, PKG_HEADER_SERIALNO_OFFSET, serial_no); + size=(data_seek-(serial_no-1)*pkg_length); + if (size>0){ + if (size>pkg_length) size=pkg_length; + blockCopy(cmd_stream, PKG_HEADER_STRUCT_SIZE, data_stream, (serial_no-1)*pkg_length, size); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE+size); + } + else{ + return 0; + } + } + + // ��ȡ���ݰ����� + public int get_pkg_count(int pkg_length){ + if ((data_seek%pkg_length)>0){ + return data_seek/pkg_length+1; + } + else{ + return data_seek/pkg_length; + } + } + + public int parse_trans_respond(byte[] packet, int size, int command, int serialno){ + size=Depack(respond_stream, packet, size); + if (size>=RESPOND_STRUCT_SIZE && asShort(respond_stream, 0)==PKC_RESPOND && + asShort(respond_stream, PKG_HEADER_STRUCT_SIZE+RESPOND_COMMAND_OFFSET)==command){ + switch (command){ + case PKC_DATA: + if (asShort(respond_stream, PKG_HEADER_STRUCT_SIZE+RESPOND_RESULT_OFFSET)==1) + { + if (serialno==asInt(respond_stream, PKG_HEADER_SERIALNO_OFFSET)) + return 1; + } + else + { + fix_serialno=asInt(respond_stream, PKG_HEADER_SERIALNO_OFFSET); + return 2; + } + break; + default: + if (serialno==asInt(respond_stream, PKG_HEADER_SERIALNO_OFFSET)) + return 1; + break; + } + } + return 0; + } + + public int parse_notify(byte[] packet, int size){ + size=Depack(respond_stream, packet, size); + if (size>=PKG_HEADER_STRUCT_SIZE && asShort(respond_stream, PKG_HEADER_COMMAND_OFFSET)==PKC_NOTIFY){ + return asInt(respond_stream, PKG_HEADER_SERIALNO_OFFSET); + } + return 0; + } + + // ��λ���ƿ���Ŀ��ʾ + public int pkg_reset_display(byte[] packet, int addr, int power) { + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_SET_POWER); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE); + } + + // ��ȡ��Դ״̬ + public int pkg_get_power(byte[] packet, int addr) { + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_GET_POWER); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE); + } + + // ���õ�Դ״̬��power=0�رյ�Դ��power=1�򿪵�Դ + public int pkg_set_power(byte[] packet, int addr, int power) { + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_SET_POWER); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + intFill(cmd_stream, PKG_HEADER_SERIALNO_OFFSET, power); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE); + } + + // ��ȡ���� + public int pkg_get_bright(byte[] packet, int addr) { + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_GET_BRIGHT); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE); + } + + // �������ȣ�bright=0��7 + public int pkg_set_bright(byte[] packet, int addr, int bright) { + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_SET_BRIGHT); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + intFill(cmd_stream, PKG_HEADER_SERIALNO_OFFSET, bright); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE); + } + + // У��ʱ�� + public int pkg_adjust_time_ex(byte[] packet, int addr, int year, int month, int week, int day, int hour, int minute, int second) { + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE+SYSTEMTIME_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_ADJUST_TIME); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + shortFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+SYSTEMTIME_YEAR_OFFSET, (short)year); + shortFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+SYSTEMTIME_MONTH_OFFSET, (short)month); + shortFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+SYSTEMTIME_WEEK_OFFSET, (short)week); + shortFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+SYSTEMTIME_DAY_OFFSET, (short)day); + shortFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+SYSTEMTIME_HOUR_OFFSET, (short)hour); + shortFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+SYSTEMTIME_MINUTE_OFFSET, (short)minute); + shortFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+SYSTEMTIME_SECOND_OFFSET, (short)second); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE+SYSTEMTIME_SIZE); + } + + // У��ʱ�� + public int pkg_adjust_time(byte[] packet, int addr) { + Calendar c = Calendar.getInstance(); + //12Сʱ�� + //return pkg_adjust_time_ex(packet, addr, c.get(Calendar.YEAR), c.get(Calendar.MONTH)+1, c.get(Calendar.DAY_OF_WEEK)-1, + // c.get(Calendar.DAY_OF_MONTH), c.get(Calendar.HOUR), c.get(Calendar.MINUTE), c.get(Calendar.SECOND)); + //24Сʱ�� + return pkg_adjust_time_ex(packet, addr, c.get(Calendar.YEAR), c.get(Calendar.MONTH)+1, c.get(Calendar.DAY_OF_WEEK)-1, + c.get(Calendar.DAY_OF_MONTH), c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), c.get(Calendar.SECOND)); + } + + // ����5V���״̬��value=0�ر�5V�����value=1����5V��� + public int pkg_set_switch(byte[] packet, int addr, int value) { + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_SET_SWITCH); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + intFill(cmd_stream, PKG_HEADER_SERIALNO_OFFSET, value); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE); + } + + // ��ȡ���ƿ����� + public int pkg_get_boardparam(byte[] packet, int addr) { + get_boardparam_respond_size = 0; + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_GET_PARAM); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE); + } + + // ���ÿ��ƿ�����_IP + public int pkg_set_boardparam_ip(byte[] packet, int addr, byte[] ip) { + int boart_param_size; + if (get_boardparam_respond_size>0) + { + boart_param_size=get_boardparam_respond_size-RESPOND_STRUCT_SIZE; + get_boardparam_respond_size = 0; + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE+boart_param_size, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_SET_PARAM); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + blockCopy(cmd_stream, PKG_HEADER_STRUCT_SIZE, respond_stream, RESPOND_STRUCT_SIZE, boart_param_size); + blockCopy(cmd_stream, PKG_HEADER_STRUCT_SIZE + BOARDPARAM_IP_OFFSET, ip, 0, 4); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE+boart_param_size); + } + return 0; + } + + // ���ö�ʱ�������ƻ� -- ��һ��7��ÿ�ն�ʱ��������ÿ�տ��Զ���3��ʱ�� + public int pkg_power_schedule_weekday(byte[] packet, int addr, boolean enabled) { + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_SET_POWER_SCHEDULE); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + if (enabled){ + intFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_ENABLED_OFFSET, 0x55AAAA55); + }else{ + intFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_ENABLED_OFFSET, 0); + } + intFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_MODE_OFFSET, 0); + + //���գ�3��������ʱ�Σ���1����6ͬ�� + // ʱ��1 + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SUNDAY_OPENTIME_OFFSET, 2015, 9, 30, 9, 0, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SUNDAY_CLOSETIME_OFFSET, 2015, 9, 30, 12, 0, 0); + // ʱ��2 + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SUNDAY_OPENTIME_OFFSET+8, 2015, 9, 30, 13, 30, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SUNDAY_CLOSETIME_OFFSET+8, 2015, 9, 30, 18, 22, 0); + // ʱ��3 + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SUNDAY_OPENTIME_OFFSET+16, 2015, 9, 30, 18, 23, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SUNDAY_CLOSETIME_OFFSET+16, 2015, 9, 30, 21, 0, 0); + //��һ + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_MONDAY_OPENTIME_OFFSET, 2015, 9, 30, 8, 30, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_MONDAY_CLOSETIME_OFFSET, 2015, 9, 30, 17, 0, 0); + //�ܶ� + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_TUESDAY_OPENTIME_OFFSET, 2015, 9, 30, 8, 30, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_TUESDAY_CLOSETIME_OFFSET, 2015, 9, 30, 17, 0, 0); + //���� + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_WEDNESDAY_OPENTIME_OFFSET, 2015, 9, 30, 8, 30, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_WEDNESDAY_CLOSETIME_OFFSET, 2015, 9, 30, 17, 0, 0); + //���� + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_THURSDAY_OPENTIME_OFFSET, 2015, 9, 30, 8, 30, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_THURSDAY_CLOSETIME_OFFSET, 2015, 9, 30, 17, 0, 0); + //���� + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_FRIDAY_OPENTIME_OFFSET, 2015, 9, 30, 8, 30, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_FRIDAY_CLOSETIME_OFFSET, 2015, 9, 30, 17, 0, 0); + //���� + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SATURDAY_OPENTIME_OFFSET, 2015, 9, 30, 9, 0, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SATURDAY_CLOSETIME_OFFSET, 2015, 9, 30, 12, 0, 0); + + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SIZE); + } + + // ���ö�ʱ�������ƻ� -- ��ָ������ֹ����ʱ�䲥�ţ�һ�����Զ���21��ʱ�� + public int pkg_power_schedule_period(byte[] packet, int addr, boolean enabled) { + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_SET_POWER_SCHEDULE); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + if (enabled){ + intFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_ENABLED_OFFSET, 0x55AAAA55); + }else{ + intFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_ENABLED_OFFSET, 0); + } + intFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_MODE_OFFSET, 1); + + //һ��21��ʱ�Σ�ÿ��ʱ��ƫ�������8���ֽ� + //��������Ϊ����һ����3�죬��һ����һ����һ������1�� + // ʱ��1 + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_OPENTIME_OFFSET, 2015, 5, 1, 0, 0, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SUNDAY_CLOSETIME_OFFSET, 2015, 5, 3, 23, 59, 59); + // ʱ��2 + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_OPENTIME_OFFSET+8, 2015, 6, 1, 0, 0, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_CLOSETIME_OFFSET+8, 2015, 6, 1, 23, 59, 59); + // ʱ��3 + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_OPENTIME_OFFSET+16, 2015, 7, 1, 0, 0, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_CLOSETIME_OFFSET+16, 2015, 7, 1, 23, 59, 59); + // ʱ��4 + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_OPENTIME_OFFSET+24, 2015, 8, 1, 0, 0, 0); + timestampFill(cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_CLOSETIME_OFFSET+24, 2015, 8, 1, 23, 59, 59); + // ...... + + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE+PWOERSCHEDULE_SIZE); + } + + // ����ת�� + public int pkg_com_transfer(byte[] packet, int addr, byte[] buffer, int size) { + blockFill(cmd_stream, 0, PKG_HEADER_STRUCT_SIZE, (byte)0); + shortFill(cmd_stream, PKG_HEADER_COMMAND_OFFSET, (short)PKC_COM_TRANSFER); + byteFill(cmd_stream, PKG_HEADER_DSTADDR_OFFSET, (byte)addr); + blockCopy(cmd_stream, PKG_HEADER_STRUCT_SIZE, buffer, 0, size); + return Pack(packet, cmd_stream, PKG_HEADER_STRUCT_SIZE+size); + } + + private void Encrypt(byte[] src, byte[] dst, int start, int size){ + int key=57943; + int key1=36028; + int key2=47926; + int vsrc, vdst; + int i; + for (i=0; i<=((size>>1)-1); i++) + { + vsrc=asShort(src, (i+(start>>1))<<1); + if (vsrc<0) vsrc=65536+vsrc; + vdst=vsrc^key; + shortFill(dst, (i+(start>>1))<<1, (short)vdst); + key=key*key1+key2; + } + } + + private int DecryptToStream(String filename, byte[] stream, int start){ + InputStream in = null; + int seek=start; + int crc1, crc2; + try { + // һ�ζ�����ֽ� + byte[] buffer = new byte[130]; + int rsize = 0; + in = new FileInputStream(filename); + // �������ֽڵ��ֽ������У�bytereadΪһ�ζ�����ֽ��� + while ((rsize = in.read(buffer)) != -1) { + if (rsize!=0){ + crc1=CreateCRC(buffer, rsize-2); + crc2=asShort(buffer, rsize - 2); + if (crc2<0) crc2=65536+crc2; + if (crc1==crc2){ + blockCopy(stream, seek, buffer, 0, rsize-2); + seek+=(rsize-2); + } + } + } + Encrypt(stream, stream, start, seek-start); + } catch (Exception e1) { + e1.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e1) { + } + } + } + return seek; + } + + public void Upgrade(String filename) { + root_seek=0; + root_count=0; + root_size=12; + blockFill(data_stream, root_seek, root_size, (byte)0); + shortFill(data_stream, root_seek, (short)0x13); + root_size=DecryptToStream(filename, data_stream, root_size); + intFill(data_stream, root_seek+ROOT_SIZE_OFFSET, root_size); + data_seek=root_seek+root_size; + } + + // ������ȡ��Դ״̬��Ӧ�� + public int parse_cmd_respond(byte[] packet, int size){ + size=Depack(respond_stream, packet, size); + if (size>=RESPOND_STRUCT_SIZE && asShort(respond_stream, 0)==PKC_RESPOND){ + switch(asShort(respond_stream, PKG_HEADER_STRUCT_SIZE+RESPOND_COMMAND_OFFSET)){ + case PKC_GET_POWER: + if (asInt(respond_stream, PKG_HEADER_SERIALNO_OFFSET)==0){ + System.out.println("��ȡ��Դ״̬��ɣ���Դ�ر�"); + }else{ + System.out.println("��ȡ��Դ״̬��ɣ���Դ����"); + } + break; + case PKC_SET_POWER: + if (asInt(respond_stream, PKG_HEADER_SERIALNO_OFFSET)==0){ + System.out.println("���õ�Դ״̬��ɣ���Դ�ر�"); + }else{ + System.out.println("���õ�Դ״̬��ɣ���Դ����"); + } + break; + case PKC_GET_BRIGHT: + System.out.println("��ȡ������ɣ�����="+asInt(respond_stream, PKG_HEADER_SERIALNO_OFFSET)); + break; + case PKC_SET_BRIGHT: + System.out.println("����������ɣ�����="+asInt(respond_stream, PKG_HEADER_SERIALNO_OFFSET)); + break; + case PKC_ADJUST_TIME: + System.out.println("У��ʱ�����"); + break; + case PKC_SET_POWER_SCHEDULE: + System.out.println("���ö�ʱ���������"); + break; + case PKC_GET_PARAM: + System.out.println("��ȡ���ƿ�������ɡ�" + + " ���="+asShort(respond_stream, RESPOND_STRUCT_SIZE+BOARDPARAM_WIDTH_OFFSET) + + " �߶�="+asShort(respond_stream, RESPOND_STRUCT_SIZE+BOARDPARAM_HEIGHT_OFFSET) + + " ��ɫ="+asShort(respond_stream, RESPOND_STRUCT_SIZE+BOARDPARAM_COLORMODE_OFFSET) + ); + get_boardparam_respond_size=size; + break; + case PKC_SET_PARAM: + System.out.println("���ÿ��ƿ��������"); + break; + } + return 1; + } + return 0; + } + + public void Compress(){ + Lzss lzss = new Lzss(); + byte[] lzss_buf = new byte[root_size + 1024]; + int lzss_size; + blockCopy(lzss_buf, 0, data_stream, 0, ROOT_STRUCT_SIZE); + lzss_size = lzss.Encode(data_stream, ROOT_STRUCT_SIZE, root_size-ROOT_STRUCT_SIZE, lzss_buf, ROOT_STRUCT_SIZE); + intFill(lzss_buf, ROOT_SIZE_OFFSET, lzss_size+ROOT_STRUCT_SIZE); + shortFill(lzss_buf, ROOT_FLAG_OFFSET, (short)(asShort(lzss_buf, ROOT_FLAG_OFFSET) | 1)); + blockCopy(data_stream, 0, lzss_buf, 0, lzss_size+ROOT_STRUCT_SIZE); + data_seek=lzss_size+ROOT_STRUCT_SIZE; + } + + public int GetDataSize(){ + return data_seek; + } + + public LEDSender2010() { + data_stream = new byte[1<<24]; + cmd_stream = new byte[1024]; + respond_stream = new byte[1024]; + packet_stream = new byte[1280]; + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/Dzp/Lzss.java b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/Lzss.java new file mode 100644 index 0000000..586ac6f --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/Lzss.java @@ -0,0 +1,164 @@ +package com.ruoyi.Dzp; + +public class Lzss { + + static int N = 4096; + static int F = 18; + static int THRESHOLD = 2; + static int NIL = N; + + static int textsize = 0; + static int codesize = 0; + static int printcount = 0; + static int text_buf[]; + static int match_position, match_length; + static int lson[], rson[], dad[]; + + public Lzss() { + lson = new int[N + 1]; + rson = new int[N + 257]; + dad = new int[N + 1]; + text_buf = new int[N + F - 1]; + } + + private static void InitTree() /* initialize trees */ + { + int i; + textsize = 0; codesize = 0; printcount = 0; + for (i = N + 1; i <= N + 256; i++) rson[i] = NIL; + for (i = 0; i < N; i++) dad[i] = NIL; + } + + private static void InsertNode(int r) + { + int i, p, cmp; + //unsigned char *key; + + //key = &text_buf[r]; + cmp = 1; p = N + 1 + text_buf[r]; + rson[r] = NIL; lson[r] = NIL; match_length = 0; + for ( ; ; ) { + if (cmp >= 0) { + if (rson[p] != NIL) p = rson[p]; + else { rson[p] = r; dad[r] = p; return; } + } else { + if (lson[p] != NIL) p = lson[p]; + else { lson[p] = r; dad[r] = p; return; } + } + for (i = 1; i < F; i++) + if ((cmp = text_buf[r + i] - text_buf[p + i]) != 0) break; + if (i > match_length) { + match_position = p; + if ((match_length = i) >= F) break; + } + } + dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p]; + dad[lson[p]] = r; dad[rson[p]] = r; + if (rson[dad[p]] == p) rson[dad[p]] = r; + else lson[dad[p]] = r; + dad[p] = NIL; + } + + private static void DeleteNode(int p) + { + int q; + + if (dad[p] == NIL) return; + if (rson[p] == NIL) q = lson[p]; + else if (lson[p] == NIL) q = rson[p]; + else { + q = lson[p]; + if (rson[q] != NIL) { + do { q = rson[q]; } while (rson[q] != NIL); + rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q]; + lson[q] = lson[p]; dad[lson[p]] = q; + } + rson[q] = rson[p]; dad[rson[p]] = q; + } + dad[q] = dad[p]; + if (rson[dad[p]] == p) rson[dad[p]] = q; else lson[dad[p]] = q; + dad[p] = NIL; + } + + public int Encode(byte[] ibuf, int istart, int isize, byte[] obuf, int ostart) + { + int i, c, len, r, s, last_match_length, code_buf_ptr; + int[] code_buf = new int[17]; + int mask; + int x, x1; + + x=x1=0; + InitTree(); + code_buf[0] = 0; + code_buf_ptr = mask = 1; + s = 0; r = N - F; + for (i = s; i < r; i++) text_buf[i] = ' '; + for (len = 0, c = 0; len < F && c < isize; len++, c++) + { + if (ibuf[istart + x] >= 0) + text_buf[r + len] = ibuf[istart + x]; + else + text_buf[r + len] = 0x100 + ibuf[istart + x]; + x++; + } + if ((textsize = len) == 0) return 0; + for (i = 1; i <= F; i++) InsertNode(r - i); + InsertNode(r); + do { + if (match_length > len) match_length = len; + if (match_length <= THRESHOLD) { + match_length = 1; + code_buf[0] |= mask; + code_buf[code_buf_ptr++] = text_buf[r]; + } else { + code_buf[code_buf_ptr++] = match_position & 0xff; + code_buf[code_buf_ptr++] = ((((match_position >> 4) & 0xf0) | (match_length - (THRESHOLD + 1))) & 0xff); + } + mask <<= 1; + mask &= 0xff; + if (mask == 0) { + if (codesize + code_buf_ptr > isize) return 0; + for (i = 0; i < code_buf_ptr; i++) + { + obuf[ostart + x1] = (byte)code_buf[i]; + x1++; + } + codesize += code_buf_ptr; + code_buf[0] = 0; code_buf_ptr = mask = 1; + } + last_match_length = match_length; + for (i = 0; i < last_match_length && c < isize; i++, c++) { + DeleteNode(s); /* Delete old strings and */ + if (ibuf[istart + x] >= 0) + text_buf[s] = ibuf[istart + x]; + else + text_buf[s] = 0x100 + ibuf[istart + x]; + if (s < F - 1) + { + if (ibuf[istart + x] >= 0) + text_buf[s + N] = ibuf[istart + x]; + else + text_buf[s + N] = 0x100 + ibuf[istart + x]; + } + s = (s + 1) & (N - 1); r = (r + 1) & (N - 1); + InsertNode(r); /* Register the string in text_buf[r..r+F-1] */ + x++; + } + while (i++ < last_match_length) { + DeleteNode(s); + s = (s + 1) & (N - 1); r = (r + 1) & (N - 1); + len--; + if (len > 0) InsertNode(r); + } + } while (len > 0); + if (code_buf_ptr > 1) { + for (i = 0; i < code_buf_ptr; i++) + { + obuf[ostart + x1] = (byte)(code_buf[i]&0xff); + x1++; + } + codesize += code_buf_ptr; + } + return x1; + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/Dzp/MyUdpSocket.java b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/MyUdpSocket.java new file mode 100644 index 0000000..76527fb --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/MyUdpSocket.java @@ -0,0 +1,93 @@ +package com.ruoyi.Dzp; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.DatagramChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.util.Set; + +public class MyUdpSocket { + private DatagramChannel channel; + private Selector selector; + private final int MAX_SIZE = 1280; + private static int client_port; + private static String client_ip; + ByteBuffer receive_buffer = ByteBuffer.allocate(MAX_SIZE); + + public MyUdpSocket(int port) throws IOException { + channel = DatagramChannel.open(); + selector = Selector.open(); + try { + //������ͨ��Ϊ������ģʽ + channel.configureBlocking(false); + //��ȡ���׽���ͨ���������׽��֣��������׽��ְ󶨵�����ָ���˿� + channel.socket().bind(new InetSocketAddress(port)); + //Ϊͨ��ѡ����ע��ͨ������ָ��������ѡ����� + channel.register(selector, SelectionKey.OP_READ); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public final void send(String ip, int port, byte[] buffer, int size) throws IOException { + InetSocketAddress client = new InetSocketAddress(ip, port); + channel.send(ByteBuffer.wrap(buffer, 0, size), client); //��EchoClient�ظ�һ�����ݱ� + } + + public final void close() throws IOException { + selector.close(); + channel.close(); + } + + public final int get_client_port() { + return client_port; + } + + public final String get_client_ip() { + return client_ip; + } + + public final void get_receive_buffer(byte[] buffer) { + receive_buffer.get(buffer); + } + + public final int receive() { + try { + receive_buffer.clear(); + if (selector.select(10) != 0) { + Set readyKeys = selector.selectedKeys(); + for (SelectionKey key : readyKeys) { + readyKeys.remove(key); + if (key.isReadable()) { + DatagramChannel dc = (DatagramChannel) key.channel(); + InetSocketAddress client = (InetSocketAddress) dc.receive(receive_buffer); //������������һ��Client�����ݱ� + if (client != null) { + client_ip = client.getAddress().getHostAddress(); + client_port = client.getPort(); + //System.out.println(client_ip+":"+client_port+" size="+receive_buffer.position()); + key.interestOps(SelectionKey.OP_READ); + return receive_buffer.position(); + } else { + return 0; + } + } else { + return 0; + } + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return 0; + } + + public final void get_receive_packet(byte[] packet, int size) { + int i; + for (i = 0; i < size; i++) { + packet[i] = receive_buffer.array()[i]; + } + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/Dzp/ProtocolDemo.java b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/ProtocolDemo.java new file mode 100644 index 0000000..0d91377 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/ProtocolDemo.java @@ -0,0 +1,995 @@ +package com.ruoyi.Dzp; + + + +import java.awt.*; +//import java.util.Calendar; + +public class ProtocolDemo { + + // ====���붯����ʽ�б�(��ֵ��0��ʼ)==== + // 0 = '���', + // 1 = '������ʾ', + // 2 = '�����ʾ', + // 3 = '�Ϲ���ʾ', + // 4 = '�ҹ���ʾ', + // 5 = '�¹���ʾ', + // 6 = '���������ʾ', + // 7 = '�����Ϲ���ʾ', + // 8 = '�����ҹ�', + // 9 = '�����¹�', + // 10 = '�м�������չ��', + // 11 = '�м�������չ��', + // 12 = '�м�������չ��', + // 13 = '������������', + // 14 = '������������', + // 15 = '��������չ��', + // 16 = '��������չ��', + // 17 = '�����Ͻ�����', + // 18 = '�����½�����', + // 19 = '�����Ͻ�����', + // 20 = '�����½�����', + // 21 = '������������', + // 22 = '������������', + // 23 = '�����Ҷ��', + // 24 = '�����Ҷ��', + // ===================================== + + // ====����������ʽ�б�(��ֵ��0��ʼ)==== + // 0 = '���', + // 1 = '����ʧ', + // 2 = '������ʧ', + // 3 = '�������м��£', + // 4 = '�������м��£', + // 5 = '�������м��£', + // 6 = '���������Ƴ�', + // 7 = '���������Ƴ�', + // 8 = '���������£', + // 9 = '�������Һ�£', + // 10 = '�����Ͻ��Ƴ�', + // 11 = '�����½��Ƴ�', + // 12 = '�����Ͻ��Ƴ�', + // 13 = '�����½��Ƴ�', + // 14 = '���������Ƴ�', + // 15 = '���������Ƴ�', + // 16 = '�����Ҷ��', + // 17 = '�����Ҷ��' + // ===================================== + + // ====ͣ��������ʽ�б�(��ֵ��0��ʼ)==== + // 0 = '��̬��ʾ', + // 1 = '��˸��ʾ' + // ===================================== + + public static MyUdpSocket my_udp; + public static LEDSender2010 ledsender = new LEDSender2010(); + //public static String ledhost = "127.0.0.1"; + public static String ledhost = "10.170.23.237"; + public static int ledport = 6666; + public static int addr = 0; + + public static void mysleep(int msec) { + try { + Thread.sleep(msec); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + //����UDP����bufferΪ�������ݣ�sizeΪ�������ݳ��� + public static void udp_send(byte[] buffer, int size) { + byte[] packet = new byte[size]; + ledsender.blockCopy(packet, 0, buffer, 0, size); + ledsender.print_stream(packet, size); + try { + my_udp.send(ledhost, ledport, packet, size); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static void udp_send1(String ip, byte[] buffer, int size) { + byte[] packet = new byte[size]; + ledsender.blockCopy(packet, 0, buffer, 0, size); + ledsender.print_stream(packet, size); + try { + my_udp.send(ip, ledport, packet, size); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + //����UDP����bufferΪ�������ݣ�sizeΪ�������ݳ��� + public static int udp_receive(byte[] buffer) { + int size = 0; + size = my_udp.receive(); + if (size > 0) { + my_udp.get_receive_packet(buffer, size); + } + return size; + } + + public static int do_command(byte[] buffer, int size) { + byte[] packet = new byte[1280]; + int tx, tx_repeat = 5; + int isize = 0; + int i; + + for (tx = 0; tx < tx_repeat; tx++) { + udp_send(buffer, size); + for (i = 0; i < 50; i++) { + isize = udp_receive(packet); + if (isize > 0 && ledsender.parse_cmd_respond(packet, isize) == 1) { + return 1; + } + } + } + System.out.println("��ʱ"); + return 0; + } + + public static void demo_reset_display() { + int size; + byte[] packet = new byte[1280]; + size = ledsender.pkg_reset_display(packet, (byte) addr, 1); + System.out.println("��λ��Ŀ��ʾ..."); + do_command(packet, size); + } + + public static void demo_power_on() { + int size; + byte[] packet = new byte[1280]; + size = ledsender.pkg_set_power(packet, (byte) addr, 1); + System.out.println("�򿪵�Դ..."); + do_command(packet, size); + } + + public static void demo_power_off() { + int size; + byte[] packet = new byte[1280]; + size = ledsender.pkg_set_power(packet, (byte) addr, 0); + System.out.println("�رյ�Դ..."); + do_command(packet, size); + } + + public static void demo_get_power() { + int size; + byte[] packet = new byte[1280]; + size = ledsender.pkg_get_power(packet, (byte) addr); + System.out.println("��ȡ��Դ״̬..."); + do_command(packet, size); + } + + public static void demo_set_bright() { + int size; + byte[] packet = new byte[1280]; + size = ledsender.pkg_set_bright(packet, (byte) addr, 7); + System.out.println("��������..."); + do_command(packet, size); + } + + public static void demo_get_bright() { + int size; + byte[] packet = new byte[1280]; + size = ledsender.pkg_get_bright(packet, (byte) addr); + System.out.println("��ȡ����..."); + do_command(packet, size); + } + + public static void demo_adjust_time() { + int size; + byte[] packet = new byte[1280]; + //Calendar calendar = Calendar.getInstance(); + //ָ��ʱ��Уʱ��12Сʱ�� + //size=ledsender.pkg_adjust_time_ex(packet, (byte)addr, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH)+1, calendar.get(Calendar.DAY_OF_WEEK)-1, calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND)); + //ָ��ʱ��Уʱ��24Сʱ�� + //size=ledsender.pkg_adjust_time_ex(packet, (byte)addr, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH)+1, calendar.get(Calendar.DAY_OF_WEEK)-1, calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND)); + //�Ե�ǰϵͳʱ��Уʱ + size = ledsender.pkg_adjust_time(packet, (byte) addr); + System.out.println("У��ʱ��..."); + do_command(packet, size); + } + + public static void demo_switch_on() { + int size; + byte[] packet = new byte[1280]; + size = ledsender.pkg_set_switch(packet, (byte) addr, 1); + System.out.println("����5V���..."); + do_command(packet, size); + } + + public static void demo_switch_off() { + int size; + byte[] packet = new byte[1280]; + size = ledsender.pkg_set_switch(packet, (byte) addr, 0); + System.out.println("�ر�5V���..."); + do_command(packet, size); + } + + public static void demo_get_boardparam() { + int size; + byte[] packet = new byte[1280]; + size = ledsender.pkg_get_boardparam(packet, (byte) addr); + System.out.println("��ȡ���ƿ�����..."); + do_command(packet, size); + } + + public static void demo_set_boardparam_ip(String ip) { + int size; + byte[] packet = new byte[1280]; + byte[] ips = new byte[4]; + int i, k, k1, x; + size = ledsender.pkg_get_boardparam(packet, (byte) addr); + System.out.println("��ȡ���ƿ�����..."); + if (do_command(packet, size) == 1) { + k = 0; + x = 0; + ip = ip + '.'; + for (i = 0; i < 4; i++) { + k1 = ip.indexOf('.', k); + if (k1 > k) { + ips[i] = (byte) Integer.parseInt(ip.substring(k, k1)); + k = k1 + 1; + x++; + } + } + if (x == 4) { + size = ledsender.pkg_set_boardparam_ip(packet, (byte) addr, ips); + if (size > 0) { + do_command(packet, size); + } + } + } + } + + public static void demo_power_schedule() { + int size; + byte[] packet = new byte[1280]; + //��һ��7��ÿ�ն�ʱ��������ÿ�տ��Զ���3��ʱ�� + size = ledsender.pkg_power_schedule_weekday(packet, (byte) addr, true); + //��ָ������ֹ����ʱ�䲥�ţ�һ�����Զ���21��ʱ�� + //size=ledsender.pkg_power_schedule_period(packet, (byte)addr, true); + System.out.println("���ö�ʱ�������ƻ�..."); + do_command(packet, size); + } + + //dib_bufferΪ����ͼƬ��RGB���飬����Ϊ�������飬�����ÿ����Ԫ����һ�����ص��RGBֵ + // ���ص�(X,Y)��RGBֵ����һ��һ��˳�����У������64����32���� + // (0,0),(0,1),(0,2),...(0,31) (1,0),(1,1),(1,2),...(1,31) (2,0),(2,1),(2,2),...(2,31) ... (63,0),(63,1),(63,2),...(63,31) + // ���ص��RGBֵ��������ʾ��0-7λ��ʾ��ɫ��8-15λ��ʾ��ɫ��16-23��ʾ��ɫ��24-31λ������0 + // ����dib_buffer[n]&0xFF ��ʾ��ɫ + // (dib_buffer[n]>>8)&0xFF ��ʾ��ɫ + // (dib_buffer[n]>>16)&0xFF ��ʾ��ɫ + public static int dib_width = 64; + public static int dib_height = 64; + public static int dib_buffer_size = dib_width * dib_height; + public static int[] dib_buffer = new int[dib_buffer_size]; + + public static void draw_dib() { + int x, y, z = 0; + int seek = 0; + int color = 0xFF; + for (x = 0; x < dib_width; x++) { + for (y = 0; y < dib_height; y++) { + dib_buffer[seek++] = color; + } + z++; + if (z >= 4) { + switch (color) { + case 0xFF: + color = 0xFF00; + break; + case 0xFF00: + color = 0xFFFF; + break; + case 0xFFFF: + color = 0xFF; + break; + default: + color = 0xFF; + break; + } + z = 0; + } + } + } + + public static void send_data() { + int size = 0; + byte[] packet = new byte[1280]; + int i, j, k, x, r; + int tx, tx_repeat = 5; + boolean ok; + //����ΪͨѶ���룬�������ݵIJ�ִ�������� + // ������UDPͨѶ������ + + //������������� + if (ledsender.GetDataSize() > (1 << 21)) { + System.out.println("LED��Ŀ���ݳ��ȳ�����ʾ���洢�ռ�"); + return; + } + + System.out.println("LED��Ŀѹ��ǰ���ݳ���" + ledsender.GetDataSize() + "�����ݰ�����" + ledsender.get_pkg_count(512)); + ledsender.Compress(); + System.out.println("LED��Ŀѹ�������ݳ���" + ledsender.GetDataSize() + "�����ݰ�����" + ledsender.get_pkg_count(512)); + + //��ʼ�� + ok = false; + //System.out.println("������ʼ��...�����к�=0"); + for (tx = 0; tx < tx_repeat; tx++) { + size = ledsender.pkg_begin(packet, addr); + udp_send(packet, size); + for (x = 0; x < 50; x++) { + size = udp_receive(packet); + if (size > 0 && ledsender.parse_trans_respond(packet, size, LEDSender2010.PKC_BEGIN, 0) > 0) { + //System.out.println("��ʼ��������ɣ����к�=0"); + ok = true; + break; + } + } + if (ok) break; + } + if (!ok) { + System.out.println("��ʱ"); + return; + } + + //���ݰ� + k = ledsender.get_pkg_count(512); + i = 1; + while (i <= k) { + ok = false; + //System.out.println("�������ݰ�...�����к�="+i); + for (tx = 0; tx < tx_repeat; tx++) { + j = i; + size = ledsender.pkg_data(packet, addr, i, 512); + udp_send(packet, size); + for (x = 0; x < 50; x++) { + size = udp_receive(packet); + if (size > 0) { + r = ledsender.parse_trans_respond(packet, size, LEDSender2010.PKC_DATA, i); + switch (r) { + case 0x1: + //System.out.println("���ݰ�������ɣ����к�="+i); + ok = true; + j = i + 1; + break; + case 0x2: + //System.out.println("���ݰ����к�У�Դ���Ӧ��="+i+"��ʵ��="+ledsender.fix_serialno); + j = ledsender.fix_serialno; + break; + } + //ok=true; + //break; + } + if (ok) break; + } + i = j; + if (ok) break; + } + if (!ok) { + System.out.println("��ʱ"); + return; + } + } + + //������ + ok = false; + //System.out.println("���ͽ�����...�����к�="+i); + for (tx = 0; tx < tx_repeat; tx++) { + size = ledsender.pkg_end(packet, addr, i); + udp_send(packet, size); + for (x = 0; x < 50; x++) { + size = udp_receive(packet); + if (size > 0 && ledsender.parse_trans_respond(packet, size, LEDSender2010.PKC_END, i) > 0) { + //System.out.println("������������ɣ����к�="+i); + ok = true; + break; + } + } + if (ok) break; + } + if (!ok) { + System.out.println("��ʱ"); + return; + } + + /* + ok=false; + for (x=0; x<100; x++){ + size=udp_receive(packet); + switch (ledsender.parse_notify(packet, size)){ + case LEDSender2010.NOTIFY_ROOT_PLAY: + System.out.println("���ͽ�Ŀ����У��ɹ�"); + ok=true; + break; + case LEDSender2010.NOTIFY_ROOT_DOWNLOAD: + System.out.println("���ؽ�Ŀ����У��ɹ�"); + ok=true; + break; + } + if (ok) break; + } + if (!ok) System.out.println("��Ŀ����У����󣬷���/����ʧ��"); + */ + } + + public static boolean send_data1(String ip) { + int size = 0; + byte[] packet = new byte[1280]; + int i, j, k, x, r; + int tx, tx_repeat = 5; + boolean ok; + // 下面为通讯代码,包括数据的拆分打包、发送 + // 由于是UDP通讯,增加 + + // 如果数据量大于上限,直接返回失败 + if (ledsender.GetDataSize() > (1 << 21)) { + System.out.println("LED节目数据长度超出显示屏存储空间"); + return false; + } + + ledsender.Compress(); + + // 起始包发送 + ok = false; + for (tx = 0; tx < tx_repeat; tx++) { + size = ledsender.pkg_begin(packet, addr); + udp_send1(ip, packet, size); + for (x = 0; x < 50; x++) { + size = udp_receive(packet); + if (size > 0 && ledsender.parse_trans_respond(packet, size, LEDSender2010.PKC_BEGIN, 0) > 0) { + ok = true; + break; + } + } + if (ok) break; + } + // 起始包超时,返回失败 + if (!ok) { + System.out.println("起始包发送超时"); + return false; + } + + // 数据包发送 + k = ledsender.get_pkg_count(512); + i = 1; + while (i <= k) { + ok = false; + for (tx = 0; tx < tx_repeat; tx++) { + j = i; + size = ledsender.pkg_data(packet, addr, i, 512); + udp_send1(ip, packet, size); + for (x = 0; x < 50; x++) { + size = udp_receive(packet); + if (size > 0) { + r = ledsender.parse_trans_respond(packet, size,LEDSender2010.PKC_DATA, i); + switch (r) { + case 0x1: + ok = true; + j = i + 1; + break; + case 0x2: + j = ledsender.fix_serialno; + break; + } + } + if (ok) break; + } + i = j; + if (ok) break; + } + // 数据包超时,返回失败 + if (!ok) { + System.out.println("数据包发送超时"); + return false; + } + } + + // 结束包发送 + ok = false; + for (tx = 0; tx < tx_repeat; tx++) { + size = ledsender.pkg_end(packet, addr, i); + udp_send1(ip, packet, size); + for (x = 0; x < 50; x++) { + size = udp_receive(packet); + if (size > 0 && ledsender.parse_trans_respond(packet, size, LEDSender2010.PKC_END, i) > 0) { + ok = true; + break; + } + } + if (ok) break; + } + // 结束包超时,返回失败 + if (!ok) { + System.out.println("结束包发送超时"); + return false; + } + + // 所有步骤执行成功,返回true + System.out.println("数据发送全部完成"); + return true; + } + + public static void demo_upgrade() { + ledsender.Upgrade("d:\\vsd.bin"); + send_data(); + } + + public static void demo_play() { + //String[] formats={"#y", "��", "#m", "��", "#d", "��", " ", "#h", ":", "#n", ":", "#s"}; + //String[] formats={"#h", ":", "#n", ":", "#s"}; + + //���ɽ�Ŀ���� + ledsender.MakeRoot(LEDSender2010.ROOT_PLAY,LEDSender2010.COLOR_TYPE_DOUBLE); + //ledsender.MakeRoot(LEDSender2010.ROOT_PLAY, LEDSender2010.COLOR_TYPE_THREE); + //ledsender.MakeRoot(LEDSender2010.ROOT_PLAY, LEDSender2010.COLOR_TYPE_FULL); + ledsender.AddChapter(1, 1000); + ledsender.AddRegion(0, 0, 256, 64); + + /* + //����ͼƬ + ledsender.AddLeaf(1, 2000); + //draw_dib(); + //ledsender.AddDib(0, 0, 64, 64, dib_buffer, dib_buffer_size, dib_width, dib_height, 1, 5, 2, 5, 0, 0, 1000); + BufferedImage bi; + try { + bi = LEDSender2010.createImageEx("�л����񹲺͹�", new Font("����", Font.BOLD, 24), Color.BLACK, Color.CYAN, 0, false, 64); + System.out.println("width:"+bi.getWidth()+"height:"+bi.getHeight()); + ledsender.AddWindow(0, 0, 64, 64, LEDSender2010.getBufferedImageRGB(bi), bi.getWidth() * bi.getHeight(), bi.getWidth(), bi.getHeight(), 2, 0, 2, 0, 0, 0, 0); + } catch (Exception e) { + e.printStackTrace(); + } + */ + + //�������֣����У�֧�ֶ��뷽ʽ�� + ledsender.AddLeaf(1, 2000); + //ledsender.AddTextJuhao(0, 0, 64, 32, "��ӭ���١�лл�ݹˡ�", "����", 24, Color.BLACK, Color.RED, 0, 2, true, 2, 0, 2, 0, 0, 0, 0); + ledsender.AddTextEx(0, 0, 128, 32, "��ӭ����",LEDSender2010.ALIGN_LEFT,LEDSender2010.ALIGN_TOP, "����", 16, Color.BLACK, new Color(255, 0, 0), 0, 1, 0, 2, 0, 0, 0, 0); + //ledsender.AddTextEx(128, 0, 160, 32, "лл�ݹ�", LEDSender2010.ALIGN_LEFT, LEDSender2010.ALIGN_TOP, "����", 16, Color.BLACK, Color.RED, 0, 1, 0, 2, 0, 0, 0, 0); + + //ledsender.AddLeaf(1, 2000); + //ledsender.AddTextEx(0, 0, 128, 32, "ͬһ���й�", LEDSender2010.ALIGN_LEFT, LEDSender2010.ALIGN_TOP, "����", 16, Color.BLACK, Color.RED, 0, 1, 0, 2, 0, 0, 0, 0); + //ledsender.AddTextEx(128, 0, 160, 32, "ͬһ������", LEDSender2010.ALIGN_LEFT, LEDSender2010.ALIGN_TOP, "����", 16, Color.BLACK, Color.RED, 0, 1, 0, 2, 0, 0, 0, 0); + + /* + //24������������ + ledsender.AddLeaf(1, 2000); + ledsender.AddString(0, 0, 64, 32, "��ӭ����abc", 2, 0, 2, 0, 0, 0, 0, 0xFF, 1); + //24��������ʱ�䣬��ʽyyyy��mm��dd�� + ledsender.AddLeaf(1, 2000); + ledsender.AddStringDateTime(0, 0, 256, 32, 0xFFFF, 1, formats, 6); + */ + + send_data(); + } + + public static void demo_play2() { + + //���ɽ�Ŀ���� + ledsender.MakeRoot(LEDSender2010.ROOT_DOWNLOAD,LEDSender2010.COLOR_TYPE_DOUBLE); + //ledsender.MakeRoot(LEDSender2010.ROOT_PLAY, LEDSender2010.COLOR_TYPE_THREE); + ledsender.AddChapter(1, 1000000); + ledsender.AddRegion(0, 0, 256, 64); + + //�������֣����У�֧�ֶ��뷽ʽ�� + ledsender.AddLeaf(1, 200000); + ledsender.AddWindows(0, 0, 64, 32); + ledsender.AddChildText("��ӭ����", "����", 16, Color.BLACK, Color.RED, 0, 0, false, 6, 0, 2, 0, 0, 0, 0); + ledsender.AddChildText("лл�ݹ�", "����", 16, Color.BLACK, Color.RED, 0, 0, false, 6, 0, 2, 0, 0, 0, 0); + + send_data(); + } + + public static void demo_play_chapterschedule() { + //String[] formats={"#y", "��", "#m", "��", "#d", "��", " ", "#h", ":", "#n", ":", "#s"}; + //String[] formats={"#h", ":", "#n", ":", "#s"}; + + //���ɽ�Ŀ���� + ledsender.MakeRoot(LEDSender2010.ROOT_PLAY,LEDSender2010.COLOR_TYPE_DOUBLE); + + ledsender.AddChapterEx(1, 1000, 1, 1, 0x7F, 2016, 8, 17, 0, 0, 0, 2016, 12, 27, 23, 59, 59); + ledsender.AddRegion(0, 0, 64, 64); + + //�������֣��Զ����У� + ledsender.AddLeaf(1, 2000); + ledsender.AddText(0, 0, 64, 32, "��ӭ����abc", "����", 14, Color.BLACK, Color.RED, 0, 2, true, 3, 0, 2, 0, 0, 0, 0); + + ledsender.AddChapterEx(1, 1000, 1, 1, 0x7F, 2016, 4, 28, 10, 10, 0, 2016, 12, 27, 23, 15, 0); + ledsender.AddRegion(0, 0, 64, 64); + + //�������֣����У�֧�ֶ��뷽ʽ�� + ledsender.AddLeaf(1, 2000); + ledsender.AddTextEx(0, 0, 64, 32, "лл�ݹ�abc",LEDSender2010.ALIGN_CENTER,LEDSender2010.ALIGN_TOP, "����", 14, Color.BLACK, Color.RED, 0, 1, 0, 2, 0, 0, 0, 0); + + send_data(); + } + + public static void demo_play_picture() { + //���ɽ�Ŀ���� + ledsender.MakeRoot(LEDSender2010.ROOT_PLAY,LEDSender2010.COLOR_TYPE_DOUBLE); + ledsender.AddChapter(1, 1000); + ledsender.AddRegion(0, 0, 64, 64); + ledsender.AddLeaf(1, 2000); + ledsender.AddPicture(0, 0, 64, 64, "c:\\demo.bmp", 1, 0, 2, 0, 0, 0, 0); + send_data(); + } + + public static void demo_play_voice() { + //���ɽ�Ŀ���� + ledsender.MakeRoot(LEDSender2010.ROOT_PLAY,LEDSender2010.COLOR_TYPE_DOUBLE); + ledsender.AddChapter(1, 1000); + ledsender.AddRegion(0, 0, 64, 64); + ledsender.AddLeaf(1, 2000); + ledsender.AddTextEx(0, 0, 64, 32, "��ӭ����",LEDSender2010.ALIGN_CENTER,LEDSender2010.ALIGN_TOP, "����", 16, Color.BLACK, Color.RED, 0, 1, 0, 2, 0, 0, 0, 0); + ledsender.AddVoice("��ӭ����", 5000, 10, 0, 5, 5, 1); + send_data(); + } + + public static void demo_datetime_play() { + String[] formats_datetime = {"#y", "��", "#m", "��", "#d", "��", " ", "#h", ":", "#n", ":", "#s"}; + String[] formats_date = {"#y", "��", "#m", "��", "#d", "��"}; + String[] formats_time = {"#h", ":", "#n", ":", "#s"}; + String[] formats_week = {"����", "#w"}; + + //���ɽ�Ŀ���� + ledsender.MakeRoot(LEDSender2010.ROOT_PLAY,LEDSender2010.COLOR_TYPE_DOUBLE); + //ledsender.MakeRoot(LEDSender2010.ROOT_PLAY, LEDSender2010.COLOR_TYPE_THREE); + ledsender.AddChapter(1, 10000); + ledsender.AddRegion(0, 0, 64, 64); + + ledsender.AddLeaf(1, 2000); + ledsender.AddDateTime(0, 0, 64, 32, formats_datetime, 12, "����", 14, Color.BLACK, Color.YELLOW, 0); + ledsender.AddLeaf(1, 2000); + ledsender.AddDateTime(0, 0, 64, 32, formats_date, 6, "����", 14, Color.BLACK, Color.RED, 0); + ledsender.AddLeaf(1, 2000); + ledsender.AddDateTime(0, 0, 64, 32, formats_time, 5, "����", 14, Color.BLACK, Color.GREEN, 0); + ledsender.AddLeaf(1, 2000); + ledsender.AddDateTime(0, 0, 64, 32, formats_week, 2, "����", 14, Color.BLACK, Color.RED, 0); + + send_data(); + } + + public static void demo_schedule_child_play() { + //���ɽ�Ŀ���� + //String[] formats_datetime={"#y", "��", "#m", "��", "#d", "��", " ", "#h", ":", "#n", ":", "#s"}; + + ledsender.MakeRoot(LEDSender2010.ROOT_PLAY,LEDSender2010.COLOR_TYPE_DOUBLE); + ledsender.AddChapter(1, 10000); + ledsender.AddRegion(0, 0, 64, 64); + + ledsender.AddLeaf(1, 2000); + ledsender.AddWindows(0, 0, 64, 32); + //ledsender.AddChildText("abc", "����", 14, Color.BLACK, Color.RED, 0, false, 1, 0, 2, 0, 0, 0, 0); + ledsender.AddChildScheduleText("��ӭ����", "����", 14, Color.BLACK, Color.RED, 0, 0, false, 1, 0, 2, 0, 0, 0, 2000, 2, 0x0, 2018, 2, 5, 7, 10, 0, 2018, 2, 6, 23, 15, 0); + ledsender.AddChildScheduleText("лл�ݹ�", "����", 14, Color.BLACK, Color.RED, 0, 0, false, 1, 0, 2, 0, 0, 0, 2000, 2, 0x0, 2018, 2, 5, 7, 10, 0, 2018, 2, 6, 23, 15, 0); + ledsender.AddChildScheduleText("ͬһ������", "����", 14, Color.BLACK, Color.RED, 0, 0, false, 1, 0, 2, 0, 0, 0, 2000, 2, 0x0, 2018, 2, 8, 7, 10, 0, 2018, 2, 9, 23, 15, 0); + ledsender.AddChildScheduleText("ͬһ������", "����", 14, Color.BLACK, Color.RED, 0, 0, false, 1, 0, 2, 0, 0, 0, 2000, 2, 0x0, 2018, 2, 8, 7, 10, 0, 2018, 2, 9, 23, 15, 0); + + send_data(); + } + + public static void demo_fontset_import(MyUdpSocket udp, String ip, int num, String text) { + byte[] packet = new byte[1024]; + byte[] s; + int i, size; + int c; + + size = 0; + try { + s = text.getBytes("GB2312"); + size = 0; + packet[size++] = 0x55; + packet[size++] = 0x25; + packet[size++] = 0x3E; + packet[size++] = (byte) (((num / 100) % 10) + 0x30); + packet[size++] = (byte) (((num / 10) % 10) + 0x30); + packet[size++] = (byte) ((num % 10) + 0x30); + for (i = 0; i < s.length; i++) { + if (s[i] >= 0) c = s[i]; + else c = (256 + s[i]); + switch (c >> 4) { + case 0: + packet[size++] = 0x30; + break; + case 1: + packet[size++] = 0x31; + break; + case 2: + packet[size++] = 0x32; + break; + case 3: + packet[size++] = 0x33; + break; + case 4: + packet[size++] = 0x34; + break; + case 5: + packet[size++] = 0x35; + break; + case 6: + packet[size++] = 0x36; + break; + case 7: + packet[size++] = 0x37; + break; + case 8: + packet[size++] = 0x38; + break; + case 9: + packet[size++] = 0x39; + break; + case 10: + packet[size++] = 0x61; + break; + case 11: + packet[size++] = 0x62; + break; + case 12: + packet[size++] = 0x63; + break; + case 13: + packet[size++] = 0x64; + break; + case 14: + packet[size++] = 0x65; + break; + case 15: + packet[size++] = 0x66; + break; + default: + packet[size++] = 0x30; + break; + } + switch (c & 0xF) { + case 0: + packet[size++] = 0x30; + break; + case 1: + packet[size++] = 0x31; + break; + case 2: + packet[size++] = 0x32; + break; + case 3: + packet[size++] = 0x33; + break; + case 4: + packet[size++] = 0x34; + break; + case 5: + packet[size++] = 0x35; + break; + case 6: + packet[size++] = 0x36; + break; + case 7: + packet[size++] = 0x37; + break; + case 8: + packet[size++] = 0x38; + break; + case 9: + packet[size++] = 0x39; + break; + case 10: + packet[size++] = 0x61; + break; + case 11: + packet[size++] = 0x62; + break; + case 12: + packet[size++] = 0x63; + break; + case 13: + packet[size++] = 0x64; + break; + case 14: + packet[size++] = 0x65; + break; + case 15: + packet[size++] = 0x66; + break; + default: + packet[size++] = 0x30; + break; + } + } + packet[size++] = 0x23; + packet[size++] = (byte) 0xAA; + } catch (Exception e) { + } + + if (size > 0) { + try { + udp = new MyUdpSocket(8868); + udp.send(ip, 6666, packet, size); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + //ֻ����һ����Ŀ + public static void demo_play_sub_chapter() { + ledsender.MakeChapter(LEDSender2010.ROOT_PLAY_CHAPTER,LEDSender2010.COLOR_TYPE_DOUBLE, 1, 0, 1, 1000); + ledsender.AddRegion(0, 0, 64, 64); + ledsender.AddLeaf(1, 2000); + ledsender.AddTextEx(0, 0, 64, 32, "abc",LEDSender2010.ALIGN_CENTER,LEDSender2010.ALIGN_TOP, "����", 14, Color.BLACK, Color.RED, 0, 1, 0, 2, 0, 0, 0, 0); + send_data(); + } + + public static void demo_play_sub_chapter_ex() { + ledsender.MakeChapterEx(LEDSender2010.ROOT_PLAY_CHAPTER,LEDSender2010.COLOR_TYPE_DOUBLE, 1, 0, 1, 1000, 1, 1, 0x7F, 2016, 8, 17, 0, 0, 0, 2016, 12, 27, 23, 59, 59); + ledsender.AddRegion(0, 0, 64, 64); + ledsender.AddLeaf(1, 2000); + ledsender.AddTextEx(0, 0, 64, 32, "abc",LEDSender2010.ALIGN_CENTER,LEDSender2010.ALIGN_TOP, "����", 14, Color.BLACK, Color.RED, 0, 1, 0, 2, 0, 0, 0, 0); + send_data(); + } + + //ֻ����һ������ + public static void demo_play_sub_region() { + ledsender.MakeRegion(LEDSender2010.ROOT_PLAY_REGION,LEDSender2010.COLOR_TYPE_DOUBLE, 1, 0, 1, 0, 16, 128, 16); + ledsender.AddLeaf(1, 2000); + ledsender.AddTextEx(0, 0, 64, 32, "abc",LEDSender2010.ALIGN_CENTER,LEDSender2010.ALIGN_TOP, "����", 14, Color.BLACK, Color.RED, 0, 1, 0, 2, 0, 0, 0, 0); + send_data(); + } + + //ֻ����һ��ҳ�� + public static void demo_play_sub_leaf() { + String[] formats_datetime = {"#h", ":", "#n", ":", "#s"}; + ledsender.MakeLeaf(LEDSender2010.ROOT_PLAY_LEAF,LEDSender2010.COLOR_TYPE_DOUBLE, 1, 0, 0, 1, 1, 1000); + ledsender.AddTextEx(0, 0, 64, 16, "abc",LEDSender2010.ALIGN_CENTER,LEDSender2010.ALIGN_TOP, "����", 14, Color.BLACK, Color.RED, 0, 1, 0, 2, 0, 0, 0, 0); + ledsender.AddDateTime(0, 16, 64, 16, formats_datetime, 12, "����", 14, Color.BLACK, Color.YELLOW, 0); + send_data(); + } + + //ֻ����һ������ + public static void demo_play_sub_object() { + ledsender.MakeObject(LEDSender2010.ROOT_PLAY_OBJECT,LEDSender2010.COLOR_TYPE_DOUBLE, 1, 0, 0, 0, 1); + //�˴�ֻ�����һ������ + ledsender.AddTextEx(0, 0, 64, 32, "abc",LEDSender2010.ALIGN_CENTER,LEDSender2010.ALIGN_TOP, "����", 12, Color.BLACK, Color.RED, 0, 1, 0, 2, 0, 0, 0, 0); + send_data(); + } + + //�Զ��巽�� ��̬��ʾ������Ϣ + public static void demo_play_chapterschedule1(String ip, String msg) { + + //���ɽ�Ŀ���� + ledsender.MakeRoot(LEDSender2010.ROOT_PLAY,LEDSender2010.COLOR_TYPE_DOUBLE); + + ledsender.AddChapterEx(1, 1000, 1, 1, 0x7F, 2016, 8, 17, 0, 0, 0, 2016, 12, 27, 23, 59, 59); + ledsender.AddRegion(0, 0, 192, 64); + + //�������֣��Զ����У� + ledsender.AddLeaf(1, 2000); + ledsender.AddText(8, 24, 192, 64, msg, "����", 16, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + + send_data1(ip); + } + + //�Զ��巽�� ��̬��ʾ������Ϣ + public static boolean demo_play_chapterschedule2(String ip, String msg1, String msg2) { + + //���ɽ�Ŀ���� + ledsender.MakeRoot(LEDSender2010.ROOT_PLAY,LEDSender2010.COLOR_TYPE_DOUBLE); + + ledsender.AddChapterEx(1, 1000, 1, 1, 0x7F, 2016, 8, 17, 0, 0, 0, 2016, 12, 27, 23, 59, 59); + ledsender.AddRegion(0, 0, 192, 64); + + //�������֣��Զ����У� + ledsender.AddLeaf(1, 2000); + ledsender.AddText(0, 11, 192, 32, msg1, "����", 16, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + ledsender.AddText(0, 37, 192, 32, msg2, "����", 16, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + + return send_data1(ip); + } + + //�Զ��巽����ʾ�������� + public static void demo_play_chapterschedule3(String ip, String msg1, String msg2, String msg3, String msg4, String msg5, String msg) { + + //���ɽ�Ŀ���� + ledsender.MakeRoot(LEDSender2010.ROOT_PLAY,LEDSender2010.COLOR_TYPE_DOUBLE); + + ledsender.AddChapterEx(1, 1000, 1, 1, 0x7F, 2016, 8, 17, 0, 0, 0, 2016, 12, 27, 23, 59, 59); + ledsender.AddRegion(0, 0, 400, 300); + + //�������֣��Զ����У� + ledsender.AddLeaf(1, 2000); + ledsender.AddText(0, 0, 192, 21, msg, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + ledsender.AddText(0, 12, 192, 21, msg1, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + ledsender.AddText(0, 24, 192, 21, msg2, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + ledsender.AddText(0, 36, 192, 22, msg3, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); +// ledsender.AddText(0, 48, 192, 22, msg4, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); +// ledsender.AddText(0, 50, 192, 22, msg5, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + + send_data1(ip); + } + + + + //�Զ��巽����ʾ�������� + public static void demo_play_chapterschedule4(String ip, String msg1, String msg2, String msg3, String msg, String msgSpec, String msgProduct, String ms7, String msg8) { + + //���ɽ�Ŀ���� + ledsender.MakeRoot(LEDSender2010.ROOT_PLAY,LEDSender2010.COLOR_TYPE_DOUBLE); + + ledsender.AddChapterEx(1, 1000, 1, 1, 0x7F, 2016, 8, 17, 0, 0, 0, 2016, 12, 27, 23, 59, 59); + ledsender.AddRegion(0, 0, 400, 300); + + //�������֣��Զ����У� + ledsender.AddLeaf(1, 2000); + ledsender.AddText(0, 0, 192, 21, msg, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + ledsender.AddText(0, 15, 192, 21, msg1, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + ledsender.AddText(0, 30, 192, 21, msg2, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + ledsender.AddText(0, 45, 192, 22, msg3, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); +// ledsender.AddText(0, 48, 192, 22, msg4, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); +// ledsender.AddText(0, 50, 192, 22, msg5, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + + send_data1(ip); + } + + + public static boolean demo_play_chapterschedule4(String ip, String msg1, String msg2, String msg3, String msg,String msg5,String msg6,String msg7,String msg8, String msgQuantity) { + + //���ɽ�Ŀ���� + ledsender.MakeRoot(LEDSender2010.ROOT_PLAY,LEDSender2010.COLOR_TYPE_DOUBLE); + + ledsender.AddChapterEx(1, 1000, 1, 1, 0x7F, 2016, 8, 17, 0, 0, 0, 2016, 12, 27, 23, 59, 59); + ledsender.AddRegion(0, 0, 400, 300); + + //�������֣��Զ����У� + ledsender.AddLeaf(1, 2000); + ledsender.AddText(0, 0, 192, 21, msg, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + ledsender.AddText(0, 15, 192, 21, msg1, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + ledsender.AddText(65, 15, 192, 21, msg6, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 7, 0, 0, 5, 3000); + ledsender.AddText(0, 30, 192, 21, msg2, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + ledsender.AddText(65, 30, 192, 21, msg5, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 7, 0, 0, 5, 3000); + ledsender.AddText(0, 45, 192, 22, msg3, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + ledsender.AddText(65, 45, 192, 22, msgQuantity, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 7, 0, 0, 5, 3000); + ledsender.AddText(0, 60, 192, 21, msg7, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 2, 0, 0, 5, 10000); + ledsender.AddText(65, 60, 192, 21, msg8, "����", 13, Color.BLACK, Color.YELLOW, 0, 2, false, 1, 0, 7, 0, 0, 5, 3000); + + + return send_data1(ip); + } + + + + + + public static void main(String[] args) { + + // TODO Auto-generated method stub + + try { + my_udp = new MyUdpSocket(8818); + } catch (Exception ex) { + ex.printStackTrace(); + } + + //demo_play(); + //demo_play_voice(); + //demo_fontset_import(my_udp, "192.168.1.99", 0, "�������123"); + //demo_reset_display(); + //demo_play_chapterschedule(); + //demo_upgrade(); + //demo_datetime_play(); + //demo_play_picture(); + //demo_schedule_child_play(); + demo_get_boardparam(); + //demo_set_boardparam_ip("192.168.1.99"); + //demo_power_off(); + //demo_power_on(); + //demo_get_power(); + //demo_set_bright(); + //demo_get_bright(); + //demo_adjust_time(); + //demo_switch_on(); + //demo_switch_off(); + //demo_power_schedule(); + + System.out.println("���н���."); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/Dzp/domain/basLed.java b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/domain/basLed.java new file mode 100644 index 0000000..175af47 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/domain/basLed.java @@ -0,0 +1,27 @@ +package com.ruoyi.Dzp.domain; + +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class basLed extends BaseEntity { + + private int id; + private String product_id; + private String spec; + private String quantity; + private String sendFlag; + private String ipAddress; + private String trayCode; + private String model; + private String productName; + private String errorMsg; + + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/Dzp/mapper/BasLedMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/mapper/BasLedMapper.java new file mode 100644 index 0000000..2f134e2 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/Dzp/mapper/BasLedMapper.java @@ -0,0 +1,15 @@ +package com.ruoyi.Dzp.mapper; + +import com.ruoyi.Dzp.domain.basLed; + +import java.util.List; + +public interface BasLedMapper { + + + List selectBasLedList(basLed BasLed); + + void updateBasLed(basLed BasLed); + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java index c52287c..2c1c54c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java @@ -1,9 +1,11 @@ package com.ruoyi; +import java.security.Security; +import java.util.Arrays; +import java.util.stream.Collectors; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableScheduling; /** @@ -17,6 +19,7 @@ public class RuoYiApplication { public static void main(String[] args) { + enableSqlServerLegacyTls(); // System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(RuoYiApplication.class, args); System.out.println(""" @@ -24,4 +27,25 @@ public class RuoYiApplication This is a text block with Unicode characters. """); } + + private static void enableSqlServerLegacyTls() + { + if (!Boolean.parseBoolean(System.getProperty("ruoyi.sqlserver.legacyTls.enabled", "true"))) + { + return; + } + + String propertyName = "jdk.tls.disabledAlgorithms"; + String disabledAlgorithms = Security.getProperty(propertyName); + if (disabledAlgorithms == null || disabledAlgorithms.isBlank()) + { + return; + } + + String compatibleAlgorithms = Arrays.stream(disabledAlgorithms.split(",")) + .map(String::trim) + .filter(algorithm -> !"TLSv1".equalsIgnoreCase(algorithm)) + .collect(Collectors.joining(", ")); + Security.setProperty(propertyName, compatibleAlgorithms); + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundAllocationResult.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundAllocationResult.java new file mode 100644 index 0000000..45f7667 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundAllocationResult.java @@ -0,0 +1,13 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.job.mydojob.domain.MydoJob; + +public record InboundAllocationResult(boolean success, String code, String message, MydoJob job) { + public static InboundAllocationResult success(MydoJob job) { + return new InboundAllocationResult(true, "READY", "Allocation completed", job); + } + + public static InboundAllocationResult failure(String code, String message) { + return new InboundAllocationResult(false, code, message, null); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundAllocationTransaction.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundAllocationTransaction.java new file mode 100644 index 0000000..0d022da --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundAllocationTransaction.java @@ -0,0 +1,78 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.algorithm.inbound.InboundAssignment; +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.repository.ReservationStatus; +import com.ruoyi.algorithm.service.InboundPlanningResult; +import com.ruoyi.algorithm.service.InboundReservationOutcome; +import com.ruoyi.job.mydojob.domain.MydoJob; +import com.ruoyi.job.mydojob.mapper.MydoJobMapper; +import org.springframework.dao.CannotAcquireLockException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class InboundAllocationTransaction { + private final SchedulingFacade facade; + private final WmsAlgorithmMapper algorithmMapper; + private final MydoJobMapper jobMapper; + + public InboundAllocationTransaction(SchedulingFacade facade, WmsAlgorithmMapper algorithmMapper, + MydoJobMapper jobMapper) { + this.facade = facade; + this.algorithmMapper = algorithmMapper; + this.jobMapper = jobMapper; + } + + @Transactional(rollbackFor = Exception.class) + public MydoJob reserveAndCommit(MydoJob job, String projectNo, InboundPlanningResult planned) { + InboundAssignment assignment = planned.plan().assignment().orElseThrow( + () -> new IllegalArgumentException("Only an accepted inbound plan can be committed")); + String reservationId = InboundReservationIds.forJob(job.getJobId()); + String warehouseId = nonBlank(job.getWarehouseId()) ? job.getWarehouseId() : facade.defaultWarehouseId(); + InboundReservationOutcome reservation = facade.reserveInbound(reservationId, warehouseId, projectNo, planned); + if (reservation.reservation().status() != ReservationStatus.RESERVED) { + String reason = reservation.reservation().reasonCode() == null + ? "Reservation conflict" : reservation.reservation().reasonCode(); + throw new CannotAcquireLockException(reason); + } + int claimed = algorithmMapper.claimInboundSpace(reservationId, warehouseId, + assignment.laneCode(), assignment.spaceId(), job.getTrayCode()); + if (claimed != 1) { + throw new CannotAcquireLockException("Inbound target changed after planning"); + } + if (algorithmMapper.assignInboundJob(job.getJobId(), assignment.spaceId()) != 1) { + throw new CannotAcquireLockException("Inbound job changed after planning"); + } + MydoJob committed = jobMapper.selectInJobByTaskNo(job.getTaskNo()); + if (committed == null) { + throw new IllegalStateException("Committed inbound job cannot be reloaded"); + } + return committed; + } + + private boolean nonBlank(String value) { + return value != null && !value.isBlank(); + } + + @Transactional(rollbackFor = Exception.class) + public MydoJob release(MydoJob job) { + String oldSpaceId = job.getCargoSpaceId(); + if (oldSpaceId == null || oldSpaceId.isBlank()) { + return job; + } + int released = algorithmMapper.releaseInboundSpace(job.getJobId(), job.getWarehouseId(), + oldSpaceId, job.getTrayCode()); + if (released != 1) { + throw new CannotAcquireLockException("Old inbound target changed or contains stock"); + } + if (algorithmMapper.clearInboundJobAssignment(job.getJobId(), oldSpaceId) != 1) { + throw new CannotAcquireLockException("Inbound job changed while releasing old target"); + } + MydoJob cleared = jobMapper.selectInJobByTaskNo(job.getTaskNo()); + if (cleared == null) { + throw new IllegalStateException("Released inbound job cannot be reloaded"); + } + return cleared; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundReservationIds.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundReservationIds.java new file mode 100644 index 0000000..0d17ddc --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundReservationIds.java @@ -0,0 +1,16 @@ +package com.ruoyi.algorithm.wms; + +import java.nio.charset.StandardCharsets; +import java.util.UUID; + +final class InboundReservationIds { + private InboundReservationIds() { + } + + static String forJob(String jobId) { + if (jobId == null || jobId.isBlank()) { + throw new IllegalArgumentException("jobId is required"); + } + return UUID.nameUUIDFromBytes(("fortucky-inbound:" + jobId).getBytes(StandardCharsets.UTF_8)).toString(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundTaskContext.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundTaskContext.java new file mode 100644 index 0000000..71b30a9 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundTaskContext.java @@ -0,0 +1,38 @@ +package com.ruoyi.algorithm.wms; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; + +public record InboundTaskContext(String projectNo, String productId, String lotNo) { + + public static InboundTaskContext from(List items) { + List values = items == null ? List.of() : items; + Set projects = distinct(values, InboundTaskItem::projectNo); + if (projects.size() != 1) { + throw new IllegalArgumentException("Inbound task must resolve to exactly one project"); + } + return new InboundTaskContext(projects.iterator().next(), uniqueOrNull(values, InboundTaskItem::productId), + uniqueOrNull(values, InboundTaskItem::lotNo)); + } + + private static String uniqueOrNull(List values, + Function extractor) { + Set distinct = distinct(values, extractor); + return distinct.size() == 1 ? distinct.iterator().next() : null; + } + + private static Set distinct(List values, + Function extractor) { + Set result = new LinkedHashSet<>(); + values.stream().filter(Objects::nonNull).map(extractor).map(InboundTaskContext::trimToNull) + .filter(Objects::nonNull).forEach(result::add); + return result; + } + + private static String trimToNull(String value) { + return value == null || value.isBlank() ? null : value.trim(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundTaskItem.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundTaskItem.java new file mode 100644 index 0000000..caf063a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/InboundTaskItem.java @@ -0,0 +1,4 @@ +package com.ruoyi.algorithm.wms; + +public record InboundTaskItem(String projectNo, String productId, String lotNo) { +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundAllocationResult.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundAllocationResult.java new file mode 100644 index 0000000..c3818c7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundAllocationResult.java @@ -0,0 +1,20 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.algorithm.integration.SchedulingDecisionStatus; +import com.ruoyi.algorithm.outbound.OutboundAssignment; + +public record OutboundAllocationResult(SchedulingDecisionStatus status, String code, String message, + OutboundAssignment assignment) { + + public static OutboundAllocationResult ready(String code, String message, OutboundAssignment assignment) { + return new OutboundAllocationResult(SchedulingDecisionStatus.READY, code, message, assignment); + } + + public static OutboundAllocationResult waiting(String code, String message) { + return new OutboundAllocationResult(SchedulingDecisionStatus.WAITING, code, message, null); + } + + public static OutboundAllocationResult rejected(String code, String message) { + return new OutboundAllocationResult(SchedulingDecisionStatus.REJECTED, code, message, null); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundStockReference.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundStockReference.java new file mode 100644 index 0000000..8954094 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundStockReference.java @@ -0,0 +1,5 @@ +package com.ruoyi.algorithm.wms; + +public record OutboundStockReference(String stockId, String trayCode, String spaceId, + String warehouseId, String projectNo, String productId) { +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowAdvance.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowAdvance.java new file mode 100644 index 0000000..7c1122b --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowAdvance.java @@ -0,0 +1,19 @@ +package com.ruoyi.algorithm.wms; + +public record OutboundWorkflowAdvance( + boolean matched, + boolean workflowCompleted, + OutboundWorkflowRuntime workflow) { + + public static OutboundWorkflowAdvance noMatch() { + return new OutboundWorkflowAdvance(false, false, null); + } + + public static OutboundWorkflowAdvance advanced(OutboundWorkflowRuntime workflow) { + return new OutboundWorkflowAdvance(true, false, workflow); + } + + public static OutboundWorkflowAdvance completed(OutboundWorkflowRuntime workflow) { + return new OutboundWorkflowAdvance(true, true, workflow); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowCoordinator.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowCoordinator.java new file mode 100644 index 0000000..0f71e18 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowCoordinator.java @@ -0,0 +1,14 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.algorithm.outbound.OutboundAssignment; +import com.ruoyi.out.outStockout.domain.OutStockout; +import com.ruoyi.out.outStockoutDetail.domain.OutStockoutDetail; + +public interface OutboundWorkflowCoordinator { + OutboundAllocationResult start(OutStockout stockout, OutStockoutDetail detail, + OutboundStockReference selectedStock, OutboundAssignment assignment); + + OutboundWorkflowAdvance onJobFinished(String jobId); + + OutboundWorkflowAdvance confirmOutbound(String trayCode); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowHeaderState.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowHeaderState.java new file mode 100644 index 0000000..7b835d0 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowHeaderState.java @@ -0,0 +1,17 @@ +package com.ruoyi.algorithm.wms; + +public record OutboundWorkflowHeaderState( + String workflowId, + String requestId, + String stockoutDetailId, + String warehouseId, + String sourceStockId, + String selectedTrayCode, + String sourceSpaceId, + String laneCode, + int floorNo, + String exitId, + String status, + int currentStep, + int totalSteps) { +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowRuntime.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowRuntime.java new file mode 100644 index 0000000..84e8198 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowRuntime.java @@ -0,0 +1,8 @@ +package com.ruoyi.algorithm.wms; + +public record OutboundWorkflowRuntime( + String workflowId, + String requestId, + String warehouseId, + int floorNo) { +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowSpaceLock.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowSpaceLock.java new file mode 100644 index 0000000..28a0986 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowSpaceLock.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.wms; + +public record OutboundWorkflowSpaceLock( + String workflowId, + String warehouseId, + String spaceId) { +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowStepState.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowStepState.java new file mode 100644 index 0000000..fd7d2f9 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowStepState.java @@ -0,0 +1,25 @@ +package com.ruoyi.algorithm.wms; + +public record OutboundWorkflowStepState( + String assignmentId, + String workflowId, + String stockoutDetailId, + String warehouseId, + int floorNo, + String requestId, + String exitId, + String phase, + String sourceSpaceId, + String targetSpaceId, + int workflowStep, + int workflowTotalSteps, + String dependsOnAssignmentId, + String stockId, + String trayCode, + String status, + String jobId) { + + public OutboundWorkflowRuntime runtime() { + return new OutboundWorkflowRuntime(workflowId, requestId, warehouseId, floorNo); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowTransaction.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowTransaction.java new file mode 100644 index 0000000..c2d291a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/OutboundWorkflowTransaction.java @@ -0,0 +1,352 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.algorithm.outbound.OutboundAssignment; +import com.ruoyi.algorithm.outbound.OutboundWorkflow; +import com.ruoyi.algorithm.outbound.OutboundWorkflowPhase; +import com.ruoyi.algorithm.outbound.OutboundWorkflowStep; +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.repository.DeepWorkflowMutationResult; +import com.ruoyi.out.outStockout.domain.OutStockout; +import com.ruoyi.out.outStockout.mapper.OutStockoutMapper; +import com.ruoyi.out.outStockoutDetail.domain.OutStockoutDetail; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +@Service +public class OutboundWorkflowTransaction { + private static final String PENDING = "PENDING"; + private static final String RUNNING = "RUNNING"; + private static final String AT_EXIT = "AT_EXIT"; + + private final WmsAlgorithmMapper mapper; + private final OutStockoutMapper stockoutMapper; + private final SchedulingFacade facade; + + public OutboundWorkflowTransaction(WmsAlgorithmMapper mapper, OutStockoutMapper stockoutMapper, + SchedulingFacade facade) { + this.mapper = mapper; + this.stockoutMapper = stockoutMapper; + this.facade = facade; + } + + @Transactional(rollbackFor = Exception.class) + public OutboundAllocationResult commitShallow(OutStockout stockout, OutStockoutDetail detail, + OutboundStockReference selected, OutboundAssignment assignment) { + if (assignment.workflow().isPresent()) { + throw new IllegalArgumentException("A shallow outbound assignment is required"); + } + String warehouseId = warehouseId(stockout); + OutboundStockReference live = mapper.selectOutboundShallowCommitStockForUpdate( + selected.stockId(), warehouseId, selected.spaceId(), + selected.trayCode(), selected.projectNo()); + if (!sameStock(selected, live) + || !Objects.equals(warehouseId, live.warehouseId()) + || !Objects.equals(assignment.sourceSpaceId(), live.spaceId()) + || !Objects.equals(assignment.trayNo(), live.trayCode())) { + return OutboundAllocationResult.waiting("SHALLOW_COMMIT_CONFLICT", + "Selected outbound stock or its outer lane positions changed before commit"); + } + + HashMap parameters = new HashMap<>(); + parameters.put("v_stockout_detail_id", detail.getStockoutDetailId()); + parameters.put("v_stock_id", live.stockId()); + parameters.put("v_result", null); + parameters.put("v_resultmsg", null); + stockoutMapper.manualAllot(parameters); + String result = String.valueOf(parameters.get("v_result")); + String message = String.valueOf(parameters.get("v_resultmsg")); + return "10".equals(result) + ? OutboundAllocationResult.ready("READY", message, assignment) + : OutboundAllocationResult.rejected("LEGACY_" + result, message); + } + + @Transactional(rollbackFor = Exception.class) + public OutboundAllocationResult start(OutStockout stockout, OutStockoutDetail detail, + OutboundStockReference targetStock, OutboundAssignment assignment) { + OutboundWorkflow workflow = assignment.workflow().orElseThrow( + () -> new IllegalArgumentException("A deep outbound workflow is required")); + String warehouseId = warehouseId(stockout); + validateStartInputs(stockout, detail, targetStock, workflow); + OutboundStockReference liveTargetStock = mapper.selectOutboundWorkflowStartStockForUpdate( + targetStock.stockId()); + validateLiveTargetStock(warehouseId, targetStock, liveTargetStock, assignment, workflow); + + Map blockersBySource = resolveBlockers( + warehouseId, workflow.steps()); + List states = workflow.steps().stream() + .map(step -> stateFor(warehouseId, stockout, detail, liveTargetStock, assignment, workflow, + step, blockersBySource)) + .toList(); + + OutboundWorkflowHeaderState header = new OutboundWorkflowHeaderState( + workflow.workflowId(), detail.getStockoutDetailId(), detail.getStockoutDetailId(), + warehouseId, liveTargetStock.stockId(), liveTargetStock.trayCode(), + workflow.sourceSpaceId(), workflow.laneCode(), workflow.floorNo(), stockout.getExitId(), + "ACTIVE", 0, workflow.steps().size()); + requireOne(mapper.insertOutboundWorkflow(header), "insert workflow header"); + for (OutboundWorkflowStepState state : states) { + requireOne(mapper.insertOutboundWorkflowStep(state), + "insert workflow step " + state.assignmentId()); + } + + Set spaces = new LinkedHashSet<>(workflow.lockedLaneSpaceIds()); + spaces.addAll(workflow.lockedBufferSpaceIds()); + for (String spaceId : spaces) { + requireOne(mapper.lockOutboundWorkflowSpace(new OutboundWorkflowSpaceLock( + workflow.workflowId(), warehouseId, spaceId)), + "lock workflow space " + spaceId); + } + + OutboundWorkflowStepState first = mapper.selectNextPendingWorkflowStep(workflow.workflowId()); + if (first == null || phase(first) != OutboundWorkflowPhase.MOVE_OUT) { + throw new IllegalStateException("Deep workflow has no executable first MOVE_OUT step"); + } + createMoveJob(first); + return OutboundAllocationResult.ready("WORKFLOW_STARTED", + "Deep outbound workflow started", assignment); + } + + @Transactional(readOnly = true) + public boolean hasActiveWorkflow(String requestId, String warehouseId, int floorNo) { + return mapper.countActiveOutboundWorkflow(requestId, warehouseId, floorNo) > 0; + } + + @Transactional(rollbackFor = Exception.class) + public OutboundWorkflowAdvance completeJob(String jobId) { + if (jobId == null || jobId.isBlank()) { + return OutboundWorkflowAdvance.noMatch(); + } + OutboundWorkflowStepState current = mapper.selectOutboundWorkflowStepByJobId(jobId.trim()); + if (current == null) { + return OutboundWorkflowAdvance.noMatch(); + } + if (!RUNNING.equals(current.status())) { + return OutboundWorkflowAdvance.noMatch(); + } + + OutboundWorkflowPhase phase = phase(current); + if (phase == OutboundWorkflowPhase.OUTBOUND) { + requireOne(mapper.markOutboundWorkflowStepAtExit(current.assignmentId()), + "mark outbound step at exit"); + return OutboundWorkflowAdvance.advanced(current.runtime()); + } + if (mapper.countStockAtSpaceByTray(current.targetSpaceId(), current.trayCode()) < 1) { + throw new IllegalStateException("Tray " + current.trayCode() + + " has not reached workflow target " + current.targetSpaceId()); + } + requireOne(mapper.markOutboundWorkflowStepCompleted(current.assignmentId()), + "complete workflow step " + current.assignmentId()); + return advanceAfterCompleted(current); + } + + @Transactional(rollbackFor = Exception.class) + public OutboundWorkflowAdvance confirmOutbound(String trayCode) { + if (trayCode == null || trayCode.isBlank()) { + return OutboundWorkflowAdvance.noMatch(); + } + OutboundWorkflowStepState outbound = mapper.selectOutboundWorkflowStepForTray(trayCode.trim()); + if (outbound == null) { + return OutboundWorkflowAdvance.noMatch(); + } + if (phase(outbound) != OutboundWorkflowPhase.OUTBOUND || !AT_EXIT.equals(outbound.status())) { + return OutboundWorkflowAdvance.noMatch(); + } + if (mapper.countStockAtSpaceByTray(outbound.sourceSpaceId(), outbound.trayCode()) != 0) { + throw new IllegalStateException("Outbound stock still exists at its original source space"); + } + requireOne(mapper.markOutboundWorkflowStepCompleted(outbound.assignmentId()), + "complete confirmed outbound step"); + + OutboundWorkflowStepState next = mapper.selectNextPendingWorkflowStep(outbound.workflowId()); + if (next == null || phase(next) != OutboundWorkflowPhase.RESTORE) { + throw new IllegalStateException("Confirmed deep outbound has no executable RESTORE step"); + } + requireOne(mapper.relockOutboundWorkflowSpace( + next.workflowId(), next.warehouseId(), next.targetSpaceId()), + "re-lock first restore target space"); + createMoveJob(next); + return OutboundWorkflowAdvance.advanced(outbound.runtime()); + } + + private OutboundWorkflowAdvance advanceAfterCompleted(OutboundWorkflowStepState current) { + OutboundWorkflowStepState next = mapper.selectNextPendingWorkflowStep(current.workflowId()); + if (next == null) { + if (phase(current) != OutboundWorkflowPhase.RESTORE) { + throw new IllegalStateException("Workflow ended before its final RESTORE step"); + } + requireOne(mapper.completeOutboundWorkflow(current.workflowId()), "complete workflow"); + int released = mapper.unlockOutboundWorkflowSpaces(current.workflowId()); + if (released < 1) { + throw new IllegalStateException("Completed workflow released no cargo spaces"); + } + DeepWorkflowMutationResult floorReleased = facade.releaseDeepWorkflowLock( + current.warehouseId(), current.requestId(), current.floorNo()); + if (!floorReleased.changed()) { + throw new IllegalStateException("Completed outbound workflow floor lock was not released"); + } + return OutboundWorkflowAdvance.completed(current.runtime()); + } + + OutboundWorkflowPhase nextPhase = phase(next); + if (nextPhase == OutboundWorkflowPhase.MOVE_OUT) { + createMoveJob(next); + } else if (nextPhase == OutboundWorkflowPhase.OUTBOUND) { + allocateOutbound(next); + } else if (nextPhase == OutboundWorkflowPhase.RESTORE) { + createMoveJob(next); + } else { + throw new IllegalStateException("Unexpected executable workflow phase " + next.phase()); + } + return OutboundWorkflowAdvance.advanced(current.runtime()); + } + + private void allocateOutbound(OutboundWorkflowStepState step) { + requireOne(mapper.unlockOutboundWorkflowSpace( + step.workflowId(), step.warehouseId(), step.sourceSpaceId()), + "unlock selected outbound source space"); + HashMap parameters = new HashMap<>(); + parameters.put("v_stockout_detail_id", step.stockoutDetailId()); + parameters.put("v_stock_id", step.stockId()); + parameters.put("v_result", null); + parameters.put("v_resultmsg", null); + stockoutMapper.manualAllot(parameters); + if (!"10".equals(String.valueOf(parameters.get("v_result")))) { + throw new IllegalStateException("Exact-stock allocation failed: " + + String.valueOf(parameters.get("v_resultmsg"))); + } + String jobId = mapper.selectActiveOutboundJobId(step.stockId(), step.stockoutDetailId()); + if (jobId == null || jobId.isBlank()) { + throw new IllegalStateException("Exact-stock allocation created no resolvable outbound job"); + } + requireOne(mapper.markOutboundWorkflowStepRunning(step.assignmentId(), jobId), + "start outbound workflow step"); + } + + private void createMoveJob(OutboundWorkflowStepState step) { + OutboundWorkflowPhase phase = phase(step); + if (phase != OutboundWorkflowPhase.MOVE_OUT && phase != OutboundWorkflowPhase.RESTORE) { + throw new IllegalStateException("Only MOVE_OUT and RESTORE steps create relocation jobs"); + } + requireOne(mapper.insertOutboundWorkflowMoveJob(step), + "create relocation job " + step.assignmentId()); + requireOne(mapper.markOutboundWorkflowStepRunning(step.assignmentId(), step.assignmentId()), + "start relocation workflow step " + step.assignmentId()); + } + + private Map resolveBlockers(String warehouseId, + List steps) { + Map blockers = new LinkedHashMap<>(); + for (OutboundWorkflowStep step : steps) { + if (step.phase() != OutboundWorkflowPhase.MOVE_OUT) { + continue; + } + List stocks = mapper.selectOutboundStocksAtSpace( + warehouseId, step.sourceSpaceId()); + if (stocks == null || stocks.isEmpty()) { + throw new IllegalStateException("No blocker stock at " + step.sourceSpaceId()); + } + OutboundStockReference selected = stocks.get(0); + boolean inconsistent = stocks.stream().anyMatch(stock -> + !selected.trayCode().equals(stock.trayCode()) + || !step.sourceSpaceId().equals(stock.spaceId()) + || !warehouseId.equals(stock.warehouseId())); + if (inconsistent) { + throw new IllegalStateException("Blocker space has inconsistent stock/tray rows: " + + step.sourceSpaceId()); + } + blockers.put(step.sourceSpaceId(), selected); + blockers.put(step.targetSpaceId(), selected); + } + return blockers; + } + + private OutboundWorkflowStepState stateFor(String warehouseId, OutStockout stockout, + OutStockoutDetail detail, + OutboundStockReference targetStock, OutboundAssignment assignment, OutboundWorkflow workflow, + OutboundWorkflowStep step, Map blockers) { + OutboundStockReference stock = switch (step.phase()) { + case OUTBOUND -> targetStock; + case MOVE_OUT -> blockers.get(step.sourceSpaceId()); + case RESTORE -> blockers.get(step.sourceSpaceId()); + }; + if (stock == null) { + throw new IllegalStateException("Cannot resolve stock for workflow step " + step.assignmentId()); + } + return new OutboundWorkflowStepState(step.assignmentId(), workflow.workflowId(), + detail.getStockoutDetailId(), warehouseId, workflow.floorNo(), + detail.getStockoutDetailId(), stockout.getExitId(), step.phase().name(), step.sourceSpaceId(), + step.targetSpaceId(), step.workflowStep(), step.workflowTotalSteps(), + step.dependsOnAssignmentId(), stock.stockId(), stock.trayCode(), PENDING, null); + } + + private void validateStartInputs(OutStockout stockout, OutStockoutDetail detail, + OutboundStockReference targetStock, OutboundWorkflow workflow) { + required(detail.getStockoutDetailId(), "stockoutDetailId"); + required(stockout.getExitId(), "exitId"); + required(targetStock.stockId(), "stockId"); + if (workflow.steps().isEmpty()) { + throw new IllegalArgumentException("Outbound workflow has no steps"); + } + } + + private void validateLiveTargetStock(String warehouseId, OutboundStockReference planned, + OutboundStockReference live, OutboundAssignment assignment, OutboundWorkflow workflow) { + if (live == null + || !Objects.equals(planned.stockId(), live.stockId()) + || !Objects.equals(planned.trayCode(), live.trayCode()) + || !Objects.equals(planned.spaceId(), live.spaceId()) + || !Objects.equals(planned.warehouseId(), live.warehouseId()) + || !Objects.equals(warehouseId, live.warehouseId()) + || !Objects.equals(assignment.sourceSpaceId(), live.spaceId()) + || !Objects.equals(assignment.trayNo(), live.trayCode()) + || !Objects.equals(workflow.sourceSpaceId(), live.spaceId())) { + throw new IllegalStateException("Selected outbound stock changed after workflow planning"); + } + } + + private boolean sameStock(OutboundStockReference planned, OutboundStockReference live) { + return live != null + && Objects.equals(planned.stockId(), live.stockId()) + && Objects.equals(planned.trayCode(), live.trayCode()) + && Objects.equals(planned.spaceId(), live.spaceId()) + && Objects.equals(planned.warehouseId(), live.warehouseId()) + && Objects.equals(planned.projectNo(), live.projectNo()); + } + + private OutboundWorkflowPhase phase(OutboundWorkflowStepState step) { + try { + return OutboundWorkflowPhase.valueOf(step.phase()); + } catch (RuntimeException exception) { + throw new IllegalStateException("Unknown outbound workflow phase " + step.phase(), exception); + } + } + + private void requireOne(int affected, String action) { + if (affected != 1) { + throw new IllegalStateException("Failed to " + action + "; affected rows=" + affected); + } + } + + private String warehouseId(OutStockout stockout) { + String warehouseId = stockout.getWarehouseId(); + if (warehouseId == null || warehouseId.isBlank()) { + warehouseId = facade.defaultWarehouseId(); + } + return required(warehouseId, "warehouseId").trim(); + } + + private String required(String value, String name) { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException(name + " is required"); + } + return value; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/PersistentOutboundWorkflowCoordinator.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/PersistentOutboundWorkflowCoordinator.java new file mode 100644 index 0000000..8f27ab1 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/PersistentOutboundWorkflowCoordinator.java @@ -0,0 +1,103 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.algorithm.integration.SchedulingDecisionStatus; +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.outbound.OutboundAssignment; +import com.ruoyi.algorithm.outbound.OutboundWorkflow; +import com.ruoyi.algorithm.repository.DeepWorkflowMutationResult; +import com.ruoyi.out.outStockout.domain.OutStockout; +import com.ruoyi.out.outStockoutDetail.domain.OutStockoutDetail; +import org.springframework.stereotype.Service; + +@Service +public class PersistentOutboundWorkflowCoordinator implements OutboundWorkflowCoordinator { + private final SchedulingFacade facade; + private final OutboundWorkflowTransaction transaction; + + public PersistentOutboundWorkflowCoordinator(SchedulingFacade facade, + OutboundWorkflowTransaction transaction) { + this.facade = facade; + this.transaction = transaction; + } + + @Override + public OutboundAllocationResult start(OutStockout stockout, OutStockoutDetail detail, + OutboundStockReference selectedStock, OutboundAssignment assignment) { + OutboundWorkflow workflow = assignment.workflow().orElseThrow( + () -> new IllegalArgumentException("A persistent outbound workflow is required")); + String warehouseId = required(stockout.getWarehouseId(), "warehouseId"); + String requestId = required(detail.getStockoutDetailId(), "stockoutDetailId"); + DeepWorkflowMutationResult acquired = facade.acquireDeepWorkflowLock( + warehouseId, requestId, workflow.floorNo()); + if (!acquired.changed()) { + return OutboundAllocationResult.waiting("WAITING_CHANNEL", + "Another deep outbound workflow owns this floor"); + } + + try { + OutboundAllocationResult result = transaction.start(stockout, detail, selectedStock, assignment); + if (result.status() != SchedulingDecisionStatus.READY) { + if (transaction.hasActiveWorkflow(requestId, warehouseId, workflow.floorNo())) { + return alreadyActive(assignment); + } + releaseAfterFailedStart(warehouseId, requestId, workflow.floorNo(), null); + } + return result; + } catch (RuntimeException failure) { + if (transaction.hasActiveWorkflow(requestId, warehouseId, workflow.floorNo())) { + return alreadyActive(assignment); + } + releaseAfterFailedStart(warehouseId, requestId, workflow.floorNo(), failure); + throw failure; + } + } + + @Override + public OutboundWorkflowAdvance onJobFinished(String jobId) { + if (!facade.routingPolicy().algorithmOwnsDecision()) { + return OutboundWorkflowAdvance.noMatch(); + } + return transaction.completeJob(jobId); + } + + @Override + public OutboundWorkflowAdvance confirmOutbound(String trayCode) { + if (!facade.routingPolicy().algorithmOwnsDecision()) { + return OutboundWorkflowAdvance.noMatch(); + } + return transaction.confirmOutbound(trayCode); + } + + private OutboundAllocationResult alreadyActive(OutboundAssignment assignment) { + return OutboundAllocationResult.ready("WORKFLOW_ALREADY_ACTIVE", + "Deep outbound workflow is already active", assignment); + } + + private void releaseAfterFailedStart(String warehouseId, String requestId, int floorNo, + RuntimeException originalFailure) { + try { + DeepWorkflowMutationResult released = facade.releaseDeepWorkflowLock( + warehouseId, requestId, floorNo); + if (!released.changed()) { + IllegalStateException releaseFailure = new IllegalStateException( + "Failed outbound workflow floor lock was not released"); + if (originalFailure == null) { + throw releaseFailure; + } + originalFailure.addSuppressed(releaseFailure); + } + } catch (RuntimeException releaseFailure) { + if (originalFailure == null) { + throw releaseFailure; + } + originalFailure.addSuppressed(releaseFailure); + } + } + + private String required(String value, String name) { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException(name + " is required"); + } + return value.trim(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/WmsInboundAllocationService.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/WmsInboundAllocationService.java new file mode 100644 index 0000000..cecead2 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/WmsInboundAllocationService.java @@ -0,0 +1,181 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.algorithm.inbound.BatchLaneMode; +import com.ruoyi.algorithm.inbound.InboundPlan; +import com.ruoyi.algorithm.inbound.InboundRequest; +import com.ruoyi.algorithm.integration.SchedulingDecisionStatus; +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.integration.SchedulingRoutingPolicy; +import com.ruoyi.algorithm.repository.ReservationStatus; +import com.ruoyi.algorithm.repository.ReservationResult; +import com.ruoyi.algorithm.service.InboundPlanningResult; +import com.ruoyi.job.mydojob.domain.MydoJob; +import com.ruoyi.job.mydojob.mapper.MydoJobMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.Set; + +@Service +public class WmsInboundAllocationService { + private static final Logger log = LoggerFactory.getLogger(WmsInboundAllocationService.class); + + private final SchedulingFacade facade; + private final WmsAlgorithmMapper algorithmMapper; + private final MydoJobMapper jobMapper; + private final InboundAllocationTransaction transaction; + private final com.ruoyi.algorithm.wms.tidy.ExecutionAdmissionService admission; + + public WmsInboundAllocationService(SchedulingFacade facade, WmsAlgorithmMapper algorithmMapper, + MydoJobMapper jobMapper, InboundAllocationTransaction transaction) { + this(facade, algorithmMapper, jobMapper, transaction, null); + } + + @Autowired + public WmsInboundAllocationService(SchedulingFacade facade, WmsAlgorithmMapper algorithmMapper, + MydoJobMapper jobMapper, InboundAllocationTransaction transaction, + com.ruoyi.algorithm.wms.tidy.ExecutionAdmissionService admission) { + this.facade = facade; + this.algorithmMapper = algorithmMapper; + this.jobMapper = jobMapper; + this.transaction = transaction; + this.admission = admission; + } + + @Transactional(rollbackFor = Exception.class) + public InboundAllocationResult allocate(MydoJob job, String deviceCode) { + admit(job); + SchedulingRoutingPolicy routing = facade.routingPolicy(); + if (!routing.runAlgorithm()) { + return legacy(job, deviceCode); + } + + InboundTaskContext context; + InboundPlanningResult planned; + try { + context = InboundTaskContext.from(algorithmMapper.selectInboundTaskItems(job.getJobId())); + planned = facade.planInbound(warehouseId(job), toRequest(job, context)); + } catch (RuntimeException exception) { + log.error("Java inbound planning failed for job {}", job.getJobId(), exception); + if (routing.runLegacy(SchedulingDecisionStatus.TECHNICAL_ERROR)) { + return legacy(job, deviceCode); + } + return InboundAllocationResult.failure("ALGORITHM_TECHNICAL_ERROR", safeMessage(exception)); + } + + InboundPlan plan = planned.plan(); + SchedulingDecisionStatus status = plan.assignment().isPresent() + ? SchedulingDecisionStatus.READY : SchedulingDecisionStatus.REJECTED; + if (routing.runLegacy(status)) { + InboundAllocationResult legacy = legacy(job, deviceCode); + String javaSpace = plan.assignment().map(value -> value.spaceId()).orElse(null); + String legacySpace = legacy.job() == null ? null : legacy.job().getCargoSpaceId(); + log.info("Inbound shadow comparison job={} javaSpace={} legacySpace={} javaRejected={}", + job.getJobId(), javaSpace, legacySpace, plan.rejection().map(value -> value.code().name()).orElse(null)); + return legacy; + } + + if (plan.rejection().isPresent()) { + var rejection = plan.rejection().orElseThrow(); + return InboundAllocationResult.failure(rejection.code().name(), rejection.reason()); + } + + try { + return InboundAllocationResult.success(transaction.reserveAndCommit(job, context.projectNo(), planned)); + } catch (RuntimeException exception) { + log.warn("Inbound commit conflicted after reservation for job {}", job.getJobId(), exception); + return InboundAllocationResult.failure("REPLAN_REQUIRED", safeMessage(exception)); + } + } + + @Transactional(rollbackFor = Exception.class) + public InboundAllocationResult reallocate(MydoJob job, String deviceCode) { + admit(job); + MydoJob cleared; + try { + cleared = transaction.release(job); + } catch (RuntimeException exception) { + log.warn("Inbound reallocation cannot release old target for job {}", job.getJobId(), exception); + return InboundAllocationResult.failure("REASSIGNMENT_CONFLICT", safeMessage(exception)); + } + + SchedulingRoutingPolicy routing = facade.routingPolicy(); + if (routing.algorithmOwnsDecision()) { + try { + String reservationId = InboundReservationIds.forJob(job.getJobId()); + ReservationResult released = facade.releaseInboundReservation(warehouseId(job), reservationId); + if (released.status() != ReservationStatus.RELEASED + && released.status() != ReservationStatus.NOT_FOUND) { + return InboundAllocationResult.failure("RESERVATION_RELEASE_FAILED", + released.reasonCode() == null ? "Old reservation cannot be released" + : released.reasonCode()); + } + } catch (RuntimeException exception) { + log.error("Inbound reallocation cannot release algorithm reservation for job {}", + job.getJobId(), exception); + return InboundAllocationResult.failure("RESERVATION_RELEASE_FAILED", safeMessage(exception)); + } + } + return allocate(cleared, deviceCode); + } + + public void completeInbound(MydoJob job) { + if (!facade.routingPolicy().algorithmOwnsDecision()) { + return; + } + String reservationId = InboundReservationIds.forJob(job.getJobId()); + ReservationResult released = facade.releaseInboundReservation(warehouseId(job), reservationId); + if (released.status() != ReservationStatus.RELEASED + && released.status() != ReservationStatus.NOT_FOUND) { + throw new IllegalStateException("Inbound reservation cannot be released: " + + (released.reasonCode() == null ? released.status().name() : released.reasonCode())); + } + } + + private InboundAllocationResult legacy(MydoJob job, String deviceCode) { + HashMap parameters = new HashMap<>(); + parameters.put("v_tray_code", job.getTrayCode()); + parameters.put("v_code", deviceCode); + parameters.put("v_result", null); + parameters.put("v_resultmsg", null); + jobMapper.allotInJobSpace(parameters); + String result = String.valueOf(parameters.get("v_result")); + if (!"10".equals(result)) { + return InboundAllocationResult.failure("LEGACY_" + result, + String.valueOf(parameters.get("v_resultmsg"))); + } + MydoJob allocated = jobMapper.selectInJobByTaskNo(job.getTaskNo()); + return allocated == null + ? InboundAllocationResult.failure("LEGACY_RESULT_MISSING", "Allocated job cannot be reloaded") + : InboundAllocationResult.success(allocated); + } + + private void admit(MydoJob job) { + if (admission != null) { + admission.assertAllowed(warehouseId(job), + com.ruoyi.algorithm.wms.tidy.ExecutionWorkType.INBOUND); + } + } + + private InboundRequest toRequest(MydoJob job, InboundTaskContext context) { + String requestId = nonBlank(job.getTaskNo()) ? job.getTaskNo() : job.getJobId(); + return new InboundRequest(requestId, job.getTrayCode(), context.projectNo(), context.productId(), + context.lotNo(), null, null, null, Set.of(), BatchLaneMode.OPEN); + } + + private String warehouseId(MydoJob job) { + return nonBlank(job.getWarehouseId()) ? job.getWarehouseId() : facade.defaultWarehouseId(); + } + + private boolean nonBlank(String value) { + return value != null && !value.isBlank(); + } + + private String safeMessage(RuntimeException exception) { + return exception.getMessage() == null ? exception.getClass().getSimpleName() : exception.getMessage(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/WmsOutboundAllocationService.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/WmsOutboundAllocationService.java new file mode 100644 index 0000000..0f7a826 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/WmsOutboundAllocationService.java @@ -0,0 +1,211 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.algorithm.integration.SchedulingDecisionStatus; +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.integration.SchedulingRoutingPolicy; +import com.ruoyi.algorithm.outbound.OutboundAssignment; +import com.ruoyi.algorithm.outbound.OutboundPlan; +import com.ruoyi.algorithm.outbound.OutboundPlanStatus; +import com.ruoyi.algorithm.outbound.OutboundRequest; +import com.ruoyi.out.outStockout.domain.OutStockout; +import com.ruoyi.out.outStockout.mapper.OutStockoutMapper; +import com.ruoyi.out.outStockoutDetail.domain.OutStockoutDetail; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.Comparator; +import java.util.List; + +@Service +public class WmsOutboundAllocationService { + private static final Logger log = LoggerFactory.getLogger(WmsOutboundAllocationService.class); + + private final SchedulingFacade facade; + private final WmsAlgorithmMapper algorithmMapper; + private final OutStockoutMapper stockoutMapper; + private final OutboundWorkflowCoordinator workflowCoordinator; + private final OutboundWorkflowTransaction workflowTransaction; + private final com.ruoyi.algorithm.wms.tidy.ExecutionAdmissionService admission; + + public WmsOutboundAllocationService(SchedulingFacade facade, WmsAlgorithmMapper algorithmMapper, + OutStockoutMapper stockoutMapper, OutboundWorkflowCoordinator workflowCoordinator, + OutboundWorkflowTransaction workflowTransaction) { + this(facade, algorithmMapper, stockoutMapper, workflowCoordinator, workflowTransaction, null); + } + + @Autowired + public WmsOutboundAllocationService(SchedulingFacade facade, WmsAlgorithmMapper algorithmMapper, + OutStockoutMapper stockoutMapper, OutboundWorkflowCoordinator workflowCoordinator, + OutboundWorkflowTransaction workflowTransaction, + com.ruoyi.algorithm.wms.tidy.ExecutionAdmissionService admission) { + this.facade = facade; + this.algorithmMapper = algorithmMapper; + this.stockoutMapper = stockoutMapper; + this.workflowCoordinator = workflowCoordinator; + this.workflowTransaction = workflowTransaction; + this.admission = admission; + } + + @Transactional(rollbackFor = Exception.class) + public OutboundAllocationResult allocateProject(OutStockout stockout, OutStockoutDetail detail) { + admit(stockout); + SchedulingRoutingPolicy routing = facade.routingPolicy(); + if (!routing.runAlgorithm()) { + return legacyAuto(detail); + } + String projectNo = trimToNull(detail.getSpare4()); + if (projectNo == null) { + return OutboundAllocationResult.rejected("PROJECT_NO_REQUIRED", + "Outbound detail has no project number"); + } + OutboundRequest request = new OutboundRequest(detail.getStockoutDetailId(), null, projectNo, + null, "OFF", 0, 1, true); + return planAndRoute(stockout, detail, request, null, true, routing); + } + + @Transactional(rollbackFor = Exception.class) + public OutboundAllocationResult allocateExactStock(OutStockout stockout, OutStockoutDetail detail, + String stockId) { + admit(stockout); + SchedulingRoutingPolicy routing = facade.routingPolicy(); + if (!routing.runAlgorithm()) { + return legacyManual(detail, stockId, null); + } + OutboundStockReference selected = algorithmMapper.selectOutboundStockReference(stockId); + if (selected == null || !warehouseId(stockout).equals(selected.warehouseId())) { + return OutboundAllocationResult.rejected("STOCK_NOT_FOUND", + "Selected stock does not exist in this warehouse"); + } + OutboundRequest request = new OutboundRequest(detail.getStockoutDetailId() + ":" + stockId, + selected.trayCode(), null, null, "OFF", 0, 1, true); + return planAndRoute(stockout, detail, request, selected, false, routing); + } + + private OutboundAllocationResult planAndRoute(OutStockout stockout, OutStockoutDetail detail, + OutboundRequest request, OutboundStockReference exactStock, boolean projectRequest, + SchedulingRoutingPolicy routing) { + OutboundPlan plan; + try { + plan = facade.planOutbound(warehouseId(stockout), request); + } catch (RuntimeException exception) { + log.error("Java outbound planning failed for detail {}", detail.getStockoutDetailId(), exception); + if (routing.runLegacy(SchedulingDecisionStatus.TECHNICAL_ERROR)) { + return projectRequest ? legacyAuto(detail) : legacyManual(detail, exactStock.stockId(), null); + } + return OutboundAllocationResult.rejected("ALGORITHM_TECHNICAL_ERROR", safeMessage(exception)); + } + + SchedulingDecisionStatus decision = decision(plan); + if (routing.runLegacy(decision)) { + OutboundAllocationResult legacy = projectRequest ? legacyAuto(detail) + : legacyManual(detail, exactStock.stockId(), null); + log.info("Outbound shadow comparison detail={} javaStatus={} javaCode={} legacyCode={}", + detail.getStockoutDetailId(), plan.status(), planCode(plan), legacy.code()); + return legacy; + } + if (plan.status() == OutboundPlanStatus.WAITING) { + var waiting = plan.waiting().orElseThrow(); + return OutboundAllocationResult.waiting(waiting.code().name(), waiting.reason()); + } + if (plan.status() == OutboundPlanStatus.ERROR) { + var error = plan.error().orElseThrow(); + return OutboundAllocationResult.rejected(error.code().name(), error.message()); + } + + OutboundAssignment assignment = plan.assignment().orElseThrow(); + OutboundStockReference selected = exactStock == null + ? resolveProjectStock(stockout, detail, assignment) : exactStock; + if (selected == null) { + return OutboundAllocationResult.rejected("AMBIGUOUS_STOCK", + "Algorithm assignment no longer resolves to one available stock row"); + } + if (!assignment.sourceSpaceId().equals(selected.spaceId()) + || !assignment.trayNo().equals(selected.trayCode())) { + return OutboundAllocationResult.rejected("ASSIGNMENT_CHANGED", + "Selected stock moved after outbound planning"); + } + if (assignment.workflow().isPresent()) { + return workflowCoordinator.start(stockout, detail, selected, assignment); + } + return workflowTransaction.commitShallow(stockout, detail, selected, assignment); + } + + private OutboundStockReference resolveProjectStock(OutStockout stockout, OutStockoutDetail detail, + OutboundAssignment assignment) { + List matches = algorithmMapper.selectOutboundStockReferences( + warehouseId(stockout), assignment.sourceSpaceId(), assignment.trayNo(), + trimToNull(detail.getSpare4())); + return matches.stream() + .min(Comparator.comparing(OutboundStockReference::stockId)) + .orElse(null); + } + + private OutboundAllocationResult legacyAuto(OutStockoutDetail detail) { + HashMap parameters = new HashMap<>(); + parameters.put("v_stockout_detail_id", detail.getStockoutDetailId()); + parameters.put("v_result", null); + parameters.put("v_resultmsg", null); + stockoutMapper.autoAllot(parameters); + return procedureResult(parameters, null); + } + + private OutboundAllocationResult legacyManual(OutStockoutDetail detail, String stockId, + OutboundAssignment assignment) { + HashMap parameters = new HashMap<>(); + parameters.put("v_stockout_detail_id", detail.getStockoutDetailId()); + parameters.put("v_stock_id", stockId); + parameters.put("v_result", null); + parameters.put("v_resultmsg", null); + stockoutMapper.manualAllot(parameters); + return procedureResult(parameters, assignment); + } + + private OutboundAllocationResult procedureResult(HashMap parameters, + OutboundAssignment assignment) { + String result = String.valueOf(parameters.get("v_result")); + String message = String.valueOf(parameters.get("v_resultmsg")); + return "10".equals(result) + ? OutboundAllocationResult.ready("READY", message, assignment) + : OutboundAllocationResult.rejected("LEGACY_" + result, message); + } + + private SchedulingDecisionStatus decision(OutboundPlan plan) { + return switch (plan.status()) { + case READY -> SchedulingDecisionStatus.READY; + case WAITING -> SchedulingDecisionStatus.WAITING; + case ERROR -> SchedulingDecisionStatus.REJECTED; + }; + } + + private String planCode(OutboundPlan plan) { + return switch (plan.status()) { + case READY -> "READY"; + case WAITING -> plan.waiting().orElseThrow().code().name(); + case ERROR -> plan.error().orElseThrow().code().name(); + }; + } + + private String warehouseId(OutStockout stockout) { + String value = trimToNull(stockout.getWarehouseId()); + return value == null ? facade.defaultWarehouseId() : value; + } + + private String trimToNull(String value) { + return value == null || value.isBlank() ? null : value.trim(); + } + + private String safeMessage(RuntimeException exception) { + return exception.getMessage() == null ? exception.getClass().getSimpleName() : exception.getMessage(); + } + + private void admit(OutStockout stockout) { + if (admission != null) { + admission.assertAllowed(warehouseId(stockout), + com.ruoyi.algorithm.wms.tidy.ExecutionWorkType.OUTBOUND); + } + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ExecutionAdmissionService.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ExecutionAdmissionService.java new file mode 100644 index 0000000..6bc485c --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ExecutionAdmissionService.java @@ -0,0 +1,32 @@ +package com.ruoyi.algorithm.wms.tidy; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Objects; + +@Service +public class ExecutionAdmissionService { + private final TidyModeService modeService; + + public ExecutionAdmissionService(TidyModeService modeService) { + this.modeService = modeService; + } + + @Transactional(propagation = Propagation.MANDATORY) + public void assertAllowed(String warehouseId, ExecutionWorkType workType) { + Objects.requireNonNull(workType, "workType"); + TidyEffectiveState state = modeService.statusForAdmission(requireWarehouse(warehouseId)).effectiveState(); + if (!workType.allowedIn(state)) { + throw new ExecutionBlockedByTidyModeException(state, workType); + } + } + + private String requireWarehouse(String warehouseId) { + if (warehouseId == null || warehouseId.isBlank()) { + throw new IllegalArgumentException("warehouseId is required"); + } + return warehouseId.trim(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ExecutionBlockedByTidyModeException.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ExecutionBlockedByTidyModeException.java new file mode 100644 index 0000000..4a6f445 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ExecutionBlockedByTidyModeException.java @@ -0,0 +1,7 @@ +package com.ruoyi.algorithm.wms.tidy; + +public class ExecutionBlockedByTidyModeException extends IllegalStateException { + public ExecutionBlockedByTidyModeException(TidyEffectiveState state, ExecutionWorkType workType) { + super("Execution work " + workType + " is blocked while tidy mode is " + state); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ExecutionWorkType.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ExecutionWorkType.java new file mode 100644 index 0000000..18fa7ed --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ExecutionWorkType.java @@ -0,0 +1,20 @@ +package com.ruoyi.algorithm.wms.tidy; + +public enum ExecutionWorkType { + DOCUMENT_RECEIPT, + INBOUND, + OUTBOUND, + OUTBOUND_RELOCATION, + AUTO_TIDY, + MANUAL_TIDY; + + public boolean allowedIn(TidyEffectiveState state) { + if (this == DOCUMENT_RECEIPT) { + return true; + } + if (state == TidyEffectiveState.NORMAL) { + return this != MANUAL_TIDY; + } + return state == TidyEffectiveState.TIDY_ACTIVE && this == MANUAL_TIDY; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ManualTidyScheduler.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ManualTidyScheduler.java new file mode 100644 index 0000000..daaaf27 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ManualTidyScheduler.java @@ -0,0 +1,78 @@ +package com.ruoyi.algorithm.wms.tidy; + +import com.ruoyi.algorithm.integration.AlgorithmProperties; +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.tidy.TidyCandidate; +import com.ruoyi.algorithm.wms.WmsAlgorithmMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.Instant; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +@Component +public class ManualTidyScheduler { + private static final Logger log = LoggerFactory.getLogger(ManualTidyScheduler.class); + + private final TidyModeService modeService; + private final WcsVehicleSnapshotClient vehicleClient; + private final TidyVehicleCapacity capacity = new TidyVehicleCapacity(); + private final SchedulingFacade facade; + private final TidyWorkflowTransaction workflows; + private final TidyWorkflowRecoveryService recovery; + private final WmsAlgorithmMapper mapper; + private final String warehouseId; + private final AlgorithmProperties properties; + + public ManualTidyScheduler(TidyModeService modeService, WcsVehicleSnapshotClient vehicleClient, + SchedulingFacade facade, TidyWorkflowTransaction workflows, TidyWorkflowRecoveryService recovery, + WmsAlgorithmMapper mapper, + AlgorithmProperties properties) { + this.modeService = modeService; + this.vehicleClient = vehicleClient; + this.facade = facade; + this.workflows = workflows; + this.recovery = recovery; + this.mapper = mapper; + this.warehouseId = properties.getWarehouseId(); + this.properties = properties; + } + + @Scheduled(fixedDelayString = "${fortucky.algorithm.tidy-reconcile-ms:5000}") + public void reconcileAndFill() { + if (properties.getMode() != com.ruoyi.algorithm.integration.SchedulingMode.ACTIVE + || !properties.isDatabaseWritesEnabled()) return; + recovery.reconcile(warehouseId); + TidyModeSnapshot mode = modeService.reconcile(warehouseId); + if (mode.effectiveState() != TidyEffectiveState.TIDY_ACTIVE || !mode.requestedEnabled()) return; + + List vehicles = vehicleClient.fetch(); + Set assigned = new HashSet<>(mapper.selectActiveManualTidyVehicleIds(warehouseId)); + TidyVehicleCapacity.CapacityResult result = capacity.calculate( + vehicles, mapper.countActiveManualTidy(warehouseId), assigned); + if (result.newSlots() == 0) return; + + Iterator vehicleIterator = vehicles.stream() + .filter(VehicleSnapshot::availableForManualTidy) + .filter(vehicle -> !assigned.contains(vehicle.vehicleId())) + .iterator(); + Iterator candidateIterator = facade.planTidy(warehouseId, Instant.now()) + .candidates().iterator(); + int remaining = result.newSlots(); + while (remaining-- > 0 && vehicleIterator.hasNext() && candidateIterator.hasNext()) { + VehicleSnapshot vehicle = vehicleIterator.next(); + TidyCandidate candidate = candidateIterator.next(); + try { + var workflowId = workflows.start(TidyOrigin.MANUAL_TIDY, warehouseId, candidate); + mapper.assignTidyWorkflowVehicle(workflowId.toString(), vehicle.vehicleId()); + } catch (RuntimeException ex) { + log.warn("Unable to start manual tidy workflow for vehicle {}", vehicle.vehicleId(), ex); + } + } + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ReplayExecutionGuard.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ReplayExecutionGuard.java new file mode 100644 index 0000000..31acf1a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/ReplayExecutionGuard.java @@ -0,0 +1,41 @@ +package com.ruoyi.algorithm.wms.tidy; + +import com.ruoyi.algorithm.integration.AlgorithmProperties; +import com.ruoyi.algorithm.integration.SchedulingMode; +import com.ruoyi.algorithm.wms.WmsAlgorithmMapper; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +@Component +public class ReplayExecutionGuard implements ApplicationRunner { + private final AlgorithmProperties properties; + private final WmsAlgorithmMapper mapper; + + public ReplayExecutionGuard(AlgorithmProperties properties, WmsAlgorithmMapper mapper) { + this.properties = properties; + this.mapper = mapper; + } + + @Override + public void run(ApplicationArguments args) { + validate(); + } + + public void validate() { + if (properties.getReplayRunId() == null || properties.getReplayRunId().isBlank()) { + return; + } + if (properties.getMode() != SchedulingMode.ACTIVE || !properties.isDatabaseWritesEnabled()) { + throw new IllegalStateException("REPLAY_REQUIRES_ACTIVE_WRITES"); + } + if (properties.getReplayDatabase() == null || properties.getReplayDatabase().isBlank()) { + throw new IllegalStateException("REPLAY_DATABASE_REQUIRED"); + } + String actual = mapper.selectDatabaseName(); + if (!properties.getReplayDatabase().equalsIgnoreCase(actual)) { + throw new IllegalStateException("REPLAY_DATABASE_MISMATCH expected=" + + properties.getReplayDatabase() + " actual=" + actual); + } + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyController.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyController.java new file mode 100644 index 0000000..042969a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyController.java @@ -0,0 +1,42 @@ +package com.ruoyi.algorithm.wms.tidy; + +import com.ruoyi.algorithm.integration.AlgorithmProperties; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@RestController +@RequestMapping("/algorithm/tidy") +public class TidyController extends BaseController { + private final TidyModeService modeService; + private final AlgorithmProperties properties; + + public TidyController(TidyModeService modeService, AlgorithmProperties properties) { + this.modeService = modeService; + this.properties = properties; + } + + @PreAuthorize("@ss.hasPermi('algorithm:tidy:query')") + @GetMapping("/status") + public AjaxResult status() { + return AjaxResult.success(modeService.status(properties.getWarehouseId())); + } + + @PreAuthorize("@ss.hasPermi('algorithm:tidy:edit')") + @PutMapping("/mode") + public AjaxResult mode(@RequestBody Map body) { + Object enabled = body == null ? null : body.get("enabled"); + if (!(enabled instanceof Boolean)) { + return AjaxResult.error("enabled must be true or false"); + } + return AjaxResult.success(modeService.requestManualMode( + properties.getWarehouseId(), (Boolean) enabled, getUsername())); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyEffectiveState.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyEffectiveState.java new file mode 100644 index 0000000..64a34b7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyEffectiveState.java @@ -0,0 +1,8 @@ +package com.ruoyi.algorithm.wms.tidy; + +public enum TidyEffectiveState { + NORMAL, + ENTERING_TIDY, + TIDY_ACTIVE, + EXITING_TIDY +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyLaneClaim.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyLaneClaim.java new file mode 100644 index 0000000..c5f06c9 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyLaneClaim.java @@ -0,0 +1,28 @@ +package com.ruoyi.algorithm.wms.tidy; + +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.UUID; + +public record TidyLaneClaim(String warehouseId, String laneCode, long dirtyVersion, + UUID claimToken, LocalDateTime leaseExpiresAt) { + public TidyLaneClaim(String warehouseId, String laneCode, long dirtyVersion, + UUID claimToken, Instant leaseExpiresAt) { + this(warehouseId, laneCode, dirtyVersion, claimToken, + leaseExpiresAt == null ? null : LocalDateTime.ofInstant(leaseExpiresAt, ZoneOffset.UTC)); + } + + public TidyLaneClaim(String warehouseId, String laneCode, long dirtyVersion, + String claimToken, Timestamp leaseExpiresAt) { + this(warehouseId, laneCode, dirtyVersion, + claimToken == null ? null : UUID.fromString(claimToken), + leaseExpiresAt == null ? null : leaseExpiresAt.toLocalDateTime()); + } + + public boolean validAt(Instant now) { + return claimToken != null && leaseExpiresAt != null + && leaseExpiresAt.isAfter(LocalDateTime.ofInstant(now, ZoneOffset.UTC)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyModeService.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyModeService.java new file mode 100644 index 0000000..a6e2c28 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyModeService.java @@ -0,0 +1,126 @@ +package com.ruoyi.algorithm.wms.tidy; + +import com.ruoyi.algorithm.wms.WmsAlgorithmMapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class TidyModeService { + private static final String SYSTEM_ACTOR = "system"; + + private final WmsAlgorithmMapper mapper; + + public TidyModeService(WmsAlgorithmMapper mapper) { + this.mapper = mapper; + } + + @Transactional(readOnly = true) + public TidyModeSnapshot status(String warehouseId) { + return requireMode(mapper.selectTidyMode(requireWarehouse(warehouseId)), warehouseId); + } + + @Transactional(propagation = Propagation.MANDATORY) + public TidyModeSnapshot statusForAdmission(String warehouseId) { + String normalizedWarehouse = requireWarehouse(warehouseId); + return requireMode(mapper.selectTidyModeForUpdate(normalizedWarehouse), normalizedWarehouse); + } + + @Transactional(rollbackFor = Exception.class) + public TidyModeSnapshot requestManualMode(String warehouseId, boolean enabled, String actor) { + String normalizedWarehouse = requireWarehouse(warehouseId); + String normalizedActor = requireActor(actor); + TidyModeSnapshot current = requireMode( + mapper.selectTidyModeForUpdate(normalizedWarehouse), normalizedWarehouse); + if (current.requestedEnabled() == enabled) { + return current; + } + + TidyEffectiveState nextState = enabled + ? TidyEffectiveState.ENTERING_TIDY + : TidyEffectiveState.EXITING_TIDY; + String reason = enabled ? "MANUAL_MODE_REQUESTED" : "MANUAL_MODE_RELEASED"; + return update(current, enabled, nextState, current.drainCount(), + current.activeTidyCount(), reason, normalizedActor); + } + + @Transactional(rollbackFor = Exception.class) + public TidyModeSnapshot reconcile(String warehouseId) { + String normalizedWarehouse = requireWarehouse(warehouseId); + TidyModeSnapshot current = requireMode( + mapper.selectTidyModeForUpdate(normalizedWarehouse), normalizedWarehouse); + int businessCount = mapper.countActiveBusinessExecution(normalizedWarehouse); + int tidyCount = mapper.countActiveManualTidy(normalizedWarehouse); + + Transition transition = transition(current, businessCount, tidyCount); + if (transition == null) { + return current.withRuntimeCounts(businessCount, tidyCount); + } + return update(current, transition.requestedEnabled(), transition.state(), + businessCount, tidyCount, transition.reason(), SYSTEM_ACTOR); + } + + private Transition transition(TidyModeSnapshot current, int businessCount, int tidyCount) { + if (current.requestedEnabled()) { + if (current.effectiveState() == TidyEffectiveState.NORMAL) { + return new Transition(true, TidyEffectiveState.ENTERING_TIDY, "MANUAL_MODE_REQUESTED"); + } + if (current.effectiveState() == TidyEffectiveState.ENTERING_TIDY && businessCount == 0) { + return new Transition(true, TidyEffectiveState.TIDY_ACTIVE, "BUSINESS_DRAINED"); + } + if (current.effectiveState() == TidyEffectiveState.EXITING_TIDY) { + TidyEffectiveState state = businessCount == 0 + ? TidyEffectiveState.TIDY_ACTIVE + : TidyEffectiveState.ENTERING_TIDY; + return new Transition(true, state, "MANUAL_MODE_REENABLED"); + } + return null; + } + + if (current.effectiveState() == TidyEffectiveState.NORMAL) { + return null; + } + if (current.effectiveState() != TidyEffectiveState.EXITING_TIDY) { + return new Transition(false, TidyEffectiveState.EXITING_TIDY, "MANUAL_MODE_RELEASED"); + } + if (businessCount == 0 && tidyCount == 0) { + return new Transition(false, TidyEffectiveState.NORMAL, "TIDY_DRAINED"); + } + return null; + } + + private TidyModeSnapshot update(TidyModeSnapshot current, boolean requested, + TidyEffectiveState state, int businessCount, int tidyCount, String reason, String actor) { + int updated = mapper.setTidyModeRequest(current.warehouseId(), requested, state.name(), + reason, actor, current.version()); + if (updated != 1) { + throw new IllegalStateException("TIDY_MODE_VERSION_CONFLICT warehouse=" + current.warehouseId() + + " expectedVersion=" + current.version()); + } + return current.transition(requested, state, businessCount, tidyCount, reason, actor); + } + + private TidyModeSnapshot requireMode(TidyModeSnapshot snapshot, String warehouseId) { + if (snapshot == null) { + throw new IllegalStateException("TIDY_MODE_NOT_INITIALIZED warehouse=" + warehouseId); + } + return snapshot; + } + + private String requireWarehouse(String warehouseId) { + if (warehouseId == null || warehouseId.isBlank()) { + throw new IllegalArgumentException("warehouseId is required"); + } + return warehouseId.trim(); + } + + private String requireActor(String actor) { + if (actor == null || actor.isBlank()) { + throw new IllegalArgumentException("actor is required"); + } + return actor.trim(); + } + + private record Transition(boolean requestedEnabled, TidyEffectiveState state, String reason) { + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyModeSnapshot.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyModeSnapshot.java new file mode 100644 index 0000000..252c606 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyModeSnapshot.java @@ -0,0 +1,26 @@ +package com.ruoyi.algorithm.wms.tidy; + +import java.time.LocalDateTime; + +public record TidyModeSnapshot( + String warehouseId, + boolean requestedEnabled, + TidyEffectiveState effectiveState, + int drainCount, + int activeTidyCount, + String statusReason, + long version, + String updatedBy, + LocalDateTime updatedAt) { + + public TidyModeSnapshot transition(boolean requested, TidyEffectiveState state, + int businessCount, int tidyCount, String reason, String actor) { + return new TidyModeSnapshot(warehouseId, requested, state, businessCount, tidyCount, + reason, version + 1, actor, LocalDateTime.now()); + } + + public TidyModeSnapshot withRuntimeCounts(int businessCount, int tidyCount) { + return new TidyModeSnapshot(warehouseId, requestedEnabled, effectiveState, + businessCount, tidyCount, statusReason, version, updatedBy, updatedAt); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyOrigin.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyOrigin.java new file mode 100644 index 0000000..f166f01 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyOrigin.java @@ -0,0 +1,3 @@ +package com.ruoyi.algorithm.wms.tidy; + +public enum TidyOrigin { AUTO_TIDY, MANUAL_TIDY } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyScheduler.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyScheduler.java new file mode 100644 index 0000000..c9e2479 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyScheduler.java @@ -0,0 +1,99 @@ +package com.ruoyi.algorithm.wms.tidy; + +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.tidy.TidyCandidate; +import com.ruoyi.algorithm.tidy.TidyPlan; +import com.ruoyi.algorithm.wms.WmsAlgorithmMapper; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.time.Instant; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Component +public class TidyScheduler { + private final TidyModeService modeService; + private final ExecutionAdmissionService admission; + private final WmsAlgorithmMapper mapper; + private final SchedulingFacade facade; + private final TidyWorkflowStarter starter; + private final String warehouseId; + private final int leaseSeconds; + private final com.ruoyi.algorithm.integration.AlgorithmProperties properties; + + public TidyScheduler(TidyModeService modeService, ExecutionAdmissionService admission, + WmsAlgorithmMapper mapper, SchedulingFacade facade, TidyWorkflowStarter starter, + com.ruoyi.algorithm.integration.AlgorithmProperties properties) { + this.modeService = modeService; + this.admission = admission; + this.mapper = mapper; + this.facade = facade; + this.starter = starter; + this.warehouseId = properties.getWarehouseId(); + this.leaseSeconds = properties.getTidyClaimLeaseSeconds(); + this.properties = properties; + } + + @Scheduled(fixedDelayString = "${fortucky.algorithm.tidy-auto-scan-ms:600000}") + @Transactional(rollbackFor = Exception.class) + public void scanAutomatic() { + if (properties.getMode() != com.ruoyi.algorithm.integration.SchedulingMode.ACTIVE + || !properties.isDatabaseWritesEnabled()) return; + if (modeService.status(warehouseId).effectiveState() != TidyEffectiveState.NORMAL) return; + TidyPlan plan = facade.planTidy(warehouseId, Instant.now()); + Map candidatesByLane = indexCandidatesBySourceLane(plan); + admission.assertAllowed(warehouseId, ExecutionWorkType.AUTO_TIDY); + if (mapper.countActiveBusinessExecution(warehouseId) > 0 || mapper.countActiveAutomaticTidy() > 0) return; + + if (candidatesByLane.isEmpty()) { + completeOneUnmatchedClaim(); + return; + } + + String eligibleLaneCodes = String.join(",", candidatesByLane.keySet()); + TidyLaneClaim claim = mapper.claimTidyLaneFromCandidates( + warehouseId, eligibleLaneCodes, "tidy-scheduler", leaseSeconds); + if (claim == null || !claim.validAt(Instant.now())) { + completeOneUnmatchedClaim(); + return; + } + try { + TidyCandidate candidate = candidatesByLane.get(claim.laneCode()); + if (candidate == null) { + releaseClaims(List.of(claim), false, "PLANNED_LANE_CLAIM_MISMATCH"); + return; + } + starter.startAutomatic(claim, candidate); + } catch (RuntimeException exception) { + releaseClaims(List.of(claim), false, exception.getMessage()); + } + } + + private void completeOneUnmatchedClaim() { + TidyLaneClaim claim = mapper.claimTidyLane(warehouseId, "tidy-scheduler", leaseSeconds); + if (claim != null && claim.validAt(Instant.now())) { + releaseClaims(List.of(claim), true, "NO_SAFE_CANDIDATE"); + } + } + + private Map indexCandidatesBySourceLane(TidyPlan plan) { + Map candidatesByLane = new LinkedHashMap<>(); + for (TidyCandidate candidate : plan.candidates()) { + candidate.moves().forEach(move -> { + String laneCode = mapper.selectLaneCodeForSpace(warehouseId, move.fromSpaceId()); + if (laneCode != null) candidatesByLane.putIfAbsent(laneCode, candidate); + }); + } + return candidatesByLane; + } + + private void releaseClaims(List claims, boolean completed, String reason) { + for (TidyLaneClaim held : claims) { + mapper.releaseTidyLane(held.warehouseId(), held.laneCode(), held.claimToken(), + held.dirtyVersion(), completed, reason); + } + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyVehicleCapacity.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyVehicleCapacity.java new file mode 100644 index 0000000..915a0fb --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyVehicleCapacity.java @@ -0,0 +1,21 @@ +package com.ruoyi.algorithm.wms.tidy; + +import java.util.List; +import java.util.Set; + +public final class TidyVehicleCapacity { + public CapacityResult calculate(List vehicles, int activeManualWorkflows, + Set assignedManualVehicleIds) { + int effective = (int) vehicles.stream() + .filter(VehicleSnapshot::availableForManualTidy) + .count(); + int assigned = assignedManualVehicleIds == null ? 0 : (int) assignedManualVehicleIds.stream() + .filter(id -> vehicles.stream().anyMatch(v -> v.vehicleId().equals(id) + && v.online() && v.healthy())) + .count(); + int available = Math.max(0, effective - Math.max(activeManualWorkflows, assigned)); + return new CapacityResult(effective, available); + } + + public record CapacityResult(int effectiveCapacity, int newSlots) { } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyWorkflowCoordinator.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyWorkflowCoordinator.java new file mode 100644 index 0000000..199ae9b --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyWorkflowCoordinator.java @@ -0,0 +1,23 @@ +package com.ruoyi.algorithm.wms.tidy; + +import com.ruoyi.algorithm.tidy.TidyCandidate; +import org.springframework.stereotype.Service; + +import java.util.UUID; + +@Service +public class TidyWorkflowCoordinator { + private final TidyWorkflowTransaction transaction; + + public TidyWorkflowCoordinator(TidyWorkflowTransaction transaction) { + this.transaction = transaction; + } + + public UUID start(TidyOrigin origin, String warehouseId, TidyCandidate candidate) { + return transaction.start(origin, warehouseId, candidate); + } + + public boolean onJobFinished(String jobId, String callbackStage) { + return transaction.onJobFinished(jobId, callbackStage); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyWorkflowStarter.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyWorkflowStarter.java new file mode 100644 index 0000000..ac8260a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/TidyWorkflowStarter.java @@ -0,0 +1,9 @@ +package com.ruoyi.algorithm.wms.tidy; + +import com.ruoyi.algorithm.tidy.TidyCandidate; + +import java.util.UUID; + +public interface TidyWorkflowStarter { + UUID startAutomatic(TidyLaneClaim claim, TidyCandidate candidate); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/VehicleSnapshot.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/VehicleSnapshot.java new file mode 100644 index 0000000..c7c54ea --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/VehicleSnapshot.java @@ -0,0 +1,8 @@ +package com.ruoyi.algorithm.wms.tidy; + +public record VehicleSnapshot(String vehicleId, boolean online, boolean healthy, + boolean idle, String taskType) { + public boolean availableForManualTidy() { + return online && healthy && idle; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/WcsVehicleSnapshotClient.java b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/WcsVehicleSnapshotClient.java new file mode 100644 index 0000000..a3e9cf6 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/algorithm/wms/tidy/WcsVehicleSnapshotClient.java @@ -0,0 +1,62 @@ +package com.ruoyi.algorithm.wms.tidy; + +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONUtil; +import com.ruoyi.algorithm.integration.AlgorithmProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +@Component +public class WcsVehicleSnapshotClient { + private static final Logger log = LoggerFactory.getLogger(WcsVehicleSnapshotClient.class); + + private final AlgorithmProperties properties; + + public WcsVehicleSnapshotClient(AlgorithmProperties properties) { + this.properties = properties; + } + + public List fetch() { + String url = properties.getTidyWcsSnapshotUrl(); + if (url == null || url.isBlank()) { + return List.of(); + } + try { + String body = HttpUtil.get(url, 3_000); + if (body == null || body.isBlank()) { + return List.of(); + } + var response = JSONUtil.parseObj(body); + Object data = response.get("data"); + if (data == null || !JSONUtil.isTypeJSON(data.toString())) { + return List.of(); + } + return JSONUtil.parseArray(data).stream() + .map(JSONUtil::parseObj) + .map(row -> new VehicleSnapshot( + firstNonBlank(row, "vehicleId", "guid", "deviceName", "deviceId"), + bool(row.get("online")), bool(row.get("healthy")), bool(row.get("idle")), + String.valueOf(row.getOrDefault("taskType", "")))) + .toList(); + } catch (Exception ex) { + log.warn("Unable to fetch WCS tidy vehicle snapshot from {}", url, ex); + return List.of(); + } + } + + private static String firstNonBlank(Map row, String... keys) { + for (String key : keys) { + Object value = row.get(key); + if (value != null && !value.toString().isBlank()) return value.toString(); + } + return "unknown"; + } + + private static boolean bool(Object value) { + return Boolean.TRUE.equals(value) || "1".equals(value) || "true".equalsIgnoreCase(String.valueOf(value)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/controller/BatchNoGenerator.java b/ruoyi-admin/src/main/java/com/ruoyi/api/controller/BatchNoGenerator.java new file mode 100644 index 0000000..96ecd84 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/controller/BatchNoGenerator.java @@ -0,0 +1,78 @@ +package com.ruoyi.api.controller; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +public class BatchNoGenerator{ + // 日期格式化模板:固定生成 yyyyMMdd 格式 + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd"); + + // 原子引用:存储当前日期,CAS保证【日期判断+重置】的原子性 + private static final AtomicReference CURRENT_DATE = + new AtomicReference<>(LocalDate.now().format(DATE_FORMATTER)); + + // 原子整数:流水号计数器,CPU级指令保证自增原子性 + private static final AtomicInteger SERIAL_NUMBER = new AtomicInteger(1); + + // 流水号最大长度(4位,最大值9999) + private static final int MAX_SERIAL = 9999; + private static final String SERIAL_FORMAT = "%04d"; + + /** + * 生成唯一批号(多线程安全,原子操作) + * @return yyyyMMdd+4位流水号 + */ + public static String generateBatchNo() { + // 获取当前系统日期 + String today = LocalDate.now().format(DATE_FORMATTER); + + // CAS自旋:保证日期判断、重置、计数的原子性 + while (true) { + // 读取缓存的日期 + String cacheDate = CURRENT_DATE.get(); + + // 场景1:当天未跨天,直接生成流水号 + if (today.equals(cacheDate)) { + // 原子自增获取当前序号 + int currentNum = SERIAL_NUMBER.getAndIncrement(); + + // 防止4位流水号溢出(超过9999) + if (currentNum > MAX_SERIAL) { + // 重置序号,抛出异常提示 + SERIAL_NUMBER.set(1); + throw new RuntimeException("当日批号已达上限:" + MAX_SERIAL); + } + + // 拼接日期+4位流水号,返回结果 + return today + String.format(SERIAL_FORMAT, currentNum); + } + + // 场景2:跨天了,CAS原子更新日期并重置流水号 + if (CURRENT_DATE.compareAndSet(cacheDate, today)) { + // 只有一个线程能执行到这里,重置为1 + SERIAL_NUMBER.set(1); + return today + String.format(SERIAL_FORMAT, 1); + } + + // CAS更新失败:说明其他线程已完成跨天重置,重新循环 + } + } + + public static void main(String[] args) throws InterruptedException { + // 模拟20个线程同时生成批号 + for (int i = 0; i < 20; i++) { + new Thread(() -> { + String batchNo = generateBatchNo(); + System.out.println("线程:" + Thread.currentThread().getName() + ",生成批号:" + batchNo); + }).start(); + } + + Thread.sleep(1000); + System.out.println("=== 所有批号生成完成,无重复、无乱序 ==="); + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/controller/ToErpApiController.java b/ruoyi-admin/src/main/java/com/ruoyi/api/controller/ToErpApiController.java index 3b0e3f0..212e2d8 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/controller/ToErpApiController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/controller/ToErpApiController.java @@ -1,13 +1,19 @@ package com.ruoyi.api.controller; +import cn.hutool.json.JSONUtil; +import com.ruoyi.api.moveMsg.domain.MoveMsg; import com.ruoyi.api.service.IToErpService; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.log.service.IRequestLogService; +import com.ruoyi.pda.mapper.PdaMapper; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.web.bind.annotation.*; import com.ruoyi.api.domain.DeliveryNoticeVo; +import java.util.HashMap; + /** * 作业统计 Controller */ @@ -19,6 +25,8 @@ public class ToErpApiController { private IToErpService toErpService; @Autowired private IRequestLogService requestLogService; + @Autowired + private PdaMapper pdaMapper; /** * 接收入出库通知单 @@ -28,7 +36,7 @@ public class ToErpApiController { public AjaxResult receiveDeliveryNotice(@RequestBody DeliveryNoticeVo deliveryNoticeVo) { AjaxResult ajaxResult = toErpService.receiveDeliveryNotice(deliveryNoticeVo); - requestLogService.insertRequestLog(requestLogService.getRequestLog(deliveryNoticeVo.toString(), "接收入出库通知单", ajaxResult)); + requestLogService.insertRequestLog(requestLogService.getRequestLogERP(JSONUtil.toJsonStr(deliveryNoticeVo), "接收入出库通知单", ajaxResult)); return ajaxResult; @@ -36,22 +44,107 @@ public class ToErpApiController { /** - * 回传其他入库单 + * 回传入库单 */ -// @Scheduled(fixedDelay = 1500) + @Scheduled(fixedDelay = 1500) @RequestMapping("/callbackInDeliveryNotice") @ResponseBody - public void callbackInDeliveryNotice() { - toErpService.callbackInDeliveryNotice(); + public void callbackInDeliveryNoticeNew() { + toErpService.callbackInDeliveryNoticeNew(); + } + + + /** + * 回传出库单(新) + */ + @Scheduled(fixedDelay = 1500) + @RequestMapping("/callbackOutDeliveryNotice") + @ResponseBody + public void callbackDeliveryOutNoticeNew() { + toErpService.callbackDeliveryOutNoticeNew(); + } + + +// @Scheduled(fixedDelay = 1500) +// @RequestMapping("/callbackOutDeliveryNotice") +// @ResponseBody +// public void callbackDeliveryOutNoticeNewS() { +// toErpService.callbackDeliveryOutNoticeNews(); +// } + + + + + +// /** +// * 回传其他入库单 +// */ +// @Scheduled(fixedDelay = 1500) +// @RequestMapping("/callbackInDeliveryNotice") +// @ResponseBody +// public void callbackInDeliveryNotice() { +// toErpService.callbackInDeliveryNotice(); +// } +// +// /** +// * 回传其他出库单 +// */ +// @Scheduled(fixedDelay = 1500) +// @RequestMapping("/callbackOutDeliveryNotice") +// @ResponseBody +// public void callbackDeliveryOutNotice() { +// toErpService.callbackoutDeliveryNotice(); +// } + + /** + * 移库回调接口 + */ + @Scheduled(fixedDelay = 1500) + @RequestMapping("/moveCargoSpace") + @ResponseBody + public void moveCargoSpace() { + toErpService.moveCargoSpace(); } /** - * 回传其他出库单 + * 自动确认入库单据 */ - @RequestMapping("/callbackOutDeliveryNotice") + @Scheduled(fixedDelay = 10000) +// @RequestMapping("/FillFinishAllot") @ResponseBody - public void callbackDeliveryOutNotice() { - toErpService.callbackoutDeliveryNotice(); + public void FillFinishAllot() { + HashMap map = new HashMap<>(); + map.put("v_result", null); + map.put("v_result_msg", null); + pdaMapper.FillFinishAllot(map); + String result = map.get("v_result").toString(); + String msg = map.get("v_result_msg").toString(); + if ("10".equals(result)) { + System.err.println(msg); + } else { +// System.err.println(msg); + } + } + /** + * 自动确认出库单据 + */ + @Scheduled(fixedDelay = 10000) +// @RequestMapping("/FillFinishAllot") + @ResponseBody + public void FillFinishAllotOut() { + HashMap map = new HashMap<>(); + map.put("v_result", null); + map.put("v_result_msg", null); + pdaMapper.FillFinishAllotOut(map); + String result = map.get("v_result").toString(); + String msg = map.get("v_result_msg").toString(); + if ("10".equals(result)) { + System.err.println(msg); + } else { +// System.err.println(msg); + } } + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/controller/ToWmsApiController.java b/ruoyi-admin/src/main/java/com/ruoyi/api/controller/ToWmsApiController.java index be1c869..a92c5cd 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/controller/ToWmsApiController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/controller/ToWmsApiController.java @@ -1,5 +1,6 @@ package com.ruoyi.api.controller; +import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.ruoyi.api.domain.ErpProduct; import com.ruoyi.api.domain.ReMaterialParam; @@ -11,6 +12,10 @@ import com.ruoyi.bas.BasProduct.service.IBasProductService; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.device.agv.domain.AgvContainerTask; +import com.ruoyi.device.agv.service.IAgvContainerTaskService; +import com.ruoyi.job.mydojob.domain.MydoJob; +import com.ruoyi.job.mydojob.mapper.MydoJobMapper; import com.ruoyi.log.domain.RequestLog; import com.ruoyi.log.service.IRequestLogService; import com.ruoyi.out.outStockout.domain.OutStockoutVo; @@ -19,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import java.util.Map; +import java.util.*; /** * 作业统计 Controller @@ -36,6 +41,10 @@ public class ToWmsApiController { private IOutStockoutService outStockoutService; @Autowired private IBasProductService basProductService; + @Autowired + private MydoJobMapper mapper; + @Autowired + private IAgvContainerTaskService agvContainerTaskService; /** * 入库请求生成作业 @@ -43,18 +52,50 @@ public class ToWmsApiController { @PostMapping("/requestEnterByTrayCode") public AjaxResult requestEnterByTrayCode(@RequestBody RequestEnter requestEnter) { AjaxResult ajaxResult = toWmsService.requestEnterByTrayCode(requestEnter); - RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(requestEnter), "入库任务创建请求",ajaxResult); + RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(requestEnter), "入库任务创建请求", ajaxResult); requestLogService.insertRequestLog(requestLog); return ajaxResult; } + // 入库分货位 + @PostMapping("/sendCargoSpace") + public AjaxResult sendCargoSpace(@RequestBody RequestEnter requestEnter) { + AjaxResult ajaxResult = toWmsService.requestEnterByTaskNo(requestEnter); + RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(requestEnter), "入库请求分配货位", ajaxResult); + requestLogService.insertRequestLog(requestLog); + return ajaxResult; + } + + + // 出库到位更新LED显示屏 + @PostMapping("/updateLed") + public AjaxResult updateLed(@RequestBody RequestEnter requestEnter) { + HashMap map = new HashMap<>(); + map.put("v_task_no", requestEnter.getTaskNo()); + map.put("v_code", requestEnter.getDeviceCode()); + mapper.updateLed(map); + return AjaxResult.success(); + } + + + // 线体报警更新报警信息 + @PostMapping("/updateLedError") + public AjaxResult updateLedError(@RequestBody RequestEnter requestEnter) { + HashMap map = new HashMap<>(); + map.put("v_code", requestEnter.getDeviceCode()); + map.put("v_error_code", requestEnter.getErrorCode()); + mapper.updateLedError(map); + return AjaxResult.success(); + } + + /** * 请求补码作业 */ @RequestMapping("/requestByNoTrayCode") public AjaxResult requestByNoTrayCode(@RequestBody RequestEnter requestEnter) { AjaxResult ajaxResult = toWmsService.selectMydoJobByEntranceId(requestEnter); - RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(requestEnter), "请求补码作业",ajaxResult); + RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(requestEnter), "请求补码作业", ajaxResult); requestLogService.insertRequestLog(requestLog); return ajaxResult; } @@ -65,7 +106,7 @@ public class ToWmsApiController { @RequestMapping("/requestEnterByTrayCodeAndEntranceId") public AjaxResult requestEnterByTrayCodeAndEntranceId(@RequestBody RequestEnter requestEnter) { AjaxResult ajaxResult = toWmsService.requestEnterByTrayCodeAndEntranceId(requestEnter); - RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(requestEnter), "获取入库作业",ajaxResult); + RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(requestEnter), "获取入库作业", ajaxResult); requestLogService.insertRequestLog(requestLog); return ajaxResult; } @@ -74,18 +115,17 @@ public class ToWmsApiController { /** * 入库、出库 任务完成回传 * Map - * "wmsType": "任务类型" 1-入库 2-出库 3-agv搬运, - * taskNo:出库 入库任务号 - * trayCode:托盘码 - * positionCode1:起点 - * positionCode2:终点 - * containerCode:容器编码 - * + * "wmsType": "任务类型" 1-入库 2-出库 3-agv搬运, + * taskNo:出库 入库任务号 + * trayCode:托盘码 + * positionCode1:起点 + * positionCode2:终点 + * containerCode:容器编码 */ @PostMapping("/jobFinish") public AjaxResult jobFinish(@RequestBody WmsJobRequest wmsJobRequest) { AjaxResult ajaxResult = toWmsService.jobFinish(wmsJobRequest); - RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(wmsJobRequest), "jobFinish",ajaxResult); + RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(wmsJobRequest), "jobFinish", ajaxResult); requestLogService.insertRequestLog(requestLog); return ajaxResult; } @@ -96,7 +136,7 @@ public class ToWmsApiController { @PostMapping("/reAssign") public AjaxResult reAssign(@RequestBody ReMaterialParam reMaterialParam) { AjaxResult ajaxResult = toWmsService.reAssign(reMaterialParam); - RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(reMaterialParam), "reAssign",ajaxResult); + RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(reMaterialParam), "reAssign", ajaxResult); requestLogService.insertRequestLog(requestLog); return ajaxResult; } @@ -107,13 +147,12 @@ public class ToWmsApiController { @PostMapping("/reMaterial") public AjaxResult reMaterial(@RequestBody ReMaterialParam reMaterialParam) { AjaxResult ajaxResult = toWmsService.reMaterial(reMaterialParam); - RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(reMaterialParam), "reMaterial",ajaxResult); + RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(reMaterialParam), "reMaterial", ajaxResult); requestLogService.insertRequestLog(requestLog); return ajaxResult; } - /** * 出库单据保存 * @@ -137,8 +176,7 @@ public class ToWmsApiController { */ @Log(title = "接收物料", businessType = BusinessType.INSERT) @PutMapping("/receiveProduct") - public AjaxResult receiveProduct(@RequestBody ErpProduct erpProduct) - { + public AjaxResult receiveProduct(@RequestBody ErpProduct erpProduct) { AjaxResult ajaxResult = toWmsService.receiveProduct(erpProduct); RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(erpProduct), "接收物料", ajaxResult); requestLogService.insertRequestLog(requestLog); @@ -150,8 +188,7 @@ public class ToWmsApiController { */ @Log(title = "修改物料管理", businessType = BusinessType.UPDATE) @PutMapping("/updateProduct") - public AjaxResult updateProduct(@RequestBody ErpProduct erpProduct) - { + public AjaxResult updateProduct(@RequestBody ErpProduct erpProduct) { AjaxResult ajaxResult = toWmsService.updateProduct(erpProduct); RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(erpProduct), "修改物料管理", ajaxResult); requestLogService.insertRequestLog(requestLog); @@ -163,12 +200,76 @@ public class ToWmsApiController { */ @Log(title = "作废物料", businessType = BusinessType.UPDATE) @PutMapping("/InvalidProduct") - public AjaxResult InvalidProduct(@RequestBody ErpProduct erpProduct) - { + public AjaxResult InvalidProduct(@RequestBody ErpProduct erpProduct) { AjaxResult ajaxResult = toWmsService.InvalidProduct(erpProduct); RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(erpProduct), "作废物料", ajaxResult); requestLogService.insertRequestLog(requestLog); return ajaxResult; } + /** + * 请求AGV执行队列 + */ +// @Log(title = "请求未下发的AGV执行队列", businessType = BusinessType.OTHER) + @RequestMapping("/queryAgvQuene") + public AjaxResult queryAgvQuene() { + AgvContainerTask agvContainerTask = new AgvContainerTask(); + agvContainerTask.setStatus("0"); + List agvContainerTasks = agvContainerTaskService.selectAgvContainerTaskList(agvContainerTask); + RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(""), "请求未下发的AGV执行队列", AjaxResult.success(agvContainerTasks)); + requestLogService.insertRequestLog(requestLog); + if (agvContainerTasks != null && agvContainerTasks.size() > 0) { + for (AgvContainerTask containerTask : agvContainerTasks) { + containerTask.setStatus("1"); + agvContainerTaskService.updateAgvContainerTask(containerTask); + } + return AjaxResult.success(agvContainerTasks.get(0)); + } else { + return AjaxResult.error("无队列"); + } + } + + + /** + * 请求AGV执行队列 + */ + @Log(title = "完成AGV执行队列", businessType = BusinessType.UPDATE) + @RequestMapping("/finishAgvQuene") + public AjaxResult finishAgvQuene(@RequestBody JSONObject jsonObject) { + String order = (String) jsonObject.get("order"); + agvContainerTaskService.deleteAgvJobByOrder(order); + return AjaxResult.success(); + + } + + + @Log(title = "自动生成Agv搬运队列到线边", businessType = BusinessType.INSERT) + @PutMapping("/insertAgvQuene") + public AjaxResult insertAgvQuene(@RequestBody WmsJobRequest wmsJobRequest) { + String taskNo = wmsJobRequest.getTaskNo();// 到位任务号 + String code = wmsJobRequest.getCode();// 线体号 + AgvContainerTask agvContainerTask = new AgvContainerTask(); + agvContainerTask.setTaskNo(taskNo); + List agvContainerTasks = agvContainerTaskService.selectAgvContainerTaskList(agvContainerTask); + if (Objects.isNull(agvContainerTasks)) { + MydoJob mydoJob = new MydoJob(); + mydoJob.setTaskNo(taskNo); + List mydoJobs = mapper.selectMydoJobList(mydoJob); + AgvContainerTask agvContainerTask1 = new AgvContainerTask(); + agvContainerTask1.setContainer(UUID.randomUUID().toString()); + agvContainerTask1.setTaskNo(taskNo); + agvContainerTask1.setStartPoint(code); + agvContainerTask1.setEndPoint(mydoJobs.get(0).getEndPoint());//TODO 需要修改 + agvContainerTask1.setSpare2(mydoJobs.get(0).getTrayCode()); + // 10缓存区到线边 11立库到线边 12 立库到缓存区 13 缓存到立库 + agvContainerTask1.setSpare1("11"); + agvContainerTask1.setStatus("0"); + agvContainerTaskService.insertAgvContainerTask(agvContainerTask1); + } + RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(wmsJobRequest), "自动生成Agv搬运队列到线边", AjaxResult.success()); + requestLogService.insertRequestLog(requestLog); + return AjaxResult.success(); + } + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/controller/TwinController.java b/ruoyi-admin/src/main/java/com/ruoyi/api/controller/TwinController.java index 7cb80c5..007d71d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/controller/TwinController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/controller/TwinController.java @@ -7,6 +7,7 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.annotation.Anonymous; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -23,6 +24,7 @@ public class TwinController { @Autowired private ITwinService twinService; + //获取所有货位 @Anonymous @GetMapping("/getEmptyCargoSpace") public AjaxResult getEmptyCargoSpace() { @@ -30,10 +32,25 @@ public class TwinController { return AjaxResult.success(list); } + //获取统计信息 @Anonymous @GetMapping("/getStockList") public Map getStockList() { return twinService.getStockListOverview(); } + //根据货位号获取库存中的物料信息 + @Anonymous + @GetMapping("/getCargo/{cargoSpaceName}") + public Map getCargo(@PathVariable("cargoSpaceName") String cargoSpaceName) { + return twinService.getCargo(cargoSpaceName); + } + + //根据任务号获取作业表中的物料信息 + @Anonymous + @GetMapping("/getTaskCargo/{taskNo}") + public Map getTaskCargo(@PathVariable("taskNo") String taskNo) { + return twinService.getTaskCargo(taskNo); + } + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/domain/CallBackErp.java b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/CallBackErp.java new file mode 100644 index 0000000..90bd28f --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/CallBackErp.java @@ -0,0 +1,70 @@ +package com.ruoyi.api.domain; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.io.Serializable; +import java.util.List; + +@NoArgsConstructor +@Data +@Getter +@Setter +public class CallBackErp implements Serializable { + + /** + + * | 方向 | 字段名 | 对应方向 | 字段名 | + * | ------- | ---------------- | -------- | -------- | + * | ERP→WMS | companyShortName | WMS→ERP | ccompany | 公司简称 + * | ERP→WMS | accountSetNo | WMS→ERP | cacc_id | 账套号 + * | ERP→WMS | warehouseId | WMS→ERP | cwhcode | 仓库 + * | ERP→WMS | customerId | WMS→ERP | cvencode | 客户 + * | ERP→WMS | customerName | WMS→ERP | cvenname | 客户名称 + * | ERP→WMS | remark | WMS→ERP | cmemo | + * + */ + // 公司名称 + @JsonProperty("ccompany") + private String ccompany; + // WMS单据号 + @JsonProperty("ccode") + private String ccode; + // 操作日期 + @JsonProperty("ddate") + private String ddate; + // 业务类型 + @JsonProperty("cintype") + private String cintype; + // 供应商编码 + @JsonProperty("cvencode") + private String cvencode; + // 供应商名称 + @JsonProperty("cvenname") + private String cvenname; + // 出/入库人 操作人 + @JsonProperty("coptname") + private String coptname; + // 仓库编码 + @JsonProperty("cwhcode") + private String cwhcode; + // 仓库名称 + @JsonProperty("cwhname") + private String cwhname; + // 备注 + @JsonProperty("cmemo") + private String cmemo; + // 账套号 + @JsonProperty("cacc_id") + private String cacc_id; + // 子明细 + @JsonProperty("details") + private List details; + + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/domain/CallBackErpItems.java b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/CallBackErpItems.java new file mode 100644 index 0000000..ac2a858 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/CallBackErpItems.java @@ -0,0 +1,68 @@ +package com.ruoyi.api.domain; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.io.Serializable; +import java.util.List; + +@NoArgsConstructor +@Data +@Getter +@Setter +public class CallBackErpItems implements Serializable { + /** + * + * | 方向 | 字段名 | 对应方向 | 字段名 | + * | ------- | ------------- | -------- | --------- | + * | ERP→WMS | lineNo | WMS→ERP | srcrowno | + * | ERP→WMS | sourceLineId | WMS→ERP | srcids | + * | ERP→WMS | oldProjectNo | WMS→ERP | cxmh | + * | ERP→WMS | projectNo | WMS→ERP | cnewxmh | + * | ERP→WMS | isBatchManage | WMS→ERP | binvbatch | + * | ERP→WMS | lotNo | WMS→ERP | cbatch | + */ + + @JsonProperty("cinvcode") + private String cinvcode; + @JsonProperty("cinvname") + private String cinvname; + @JsonProperty("cinvstd") + private String cinvstd; + @JsonProperty("cinvm_unit") + private String cinvm_unit; + @JsonProperty("cposcode") + private String cposcode; + @JsonProperty("cposname") + private String cposname; + @JsonProperty("ctrayname") + private String ctrayname; + @JsonProperty("cbatch") + private String cbatch; + @JsonProperty("iquantity") + private Integer iquantity; + @JsonProperty("cxmh") + private String cxmh; + @JsonProperty("cnewxmh") + private String cnewxmh; + @JsonProperty("srccode") + private String srccode; + @JsonProperty("srcids") + private Integer srcids; + @JsonProperty("srcrowno") + private String srcrowno; + @JsonProperty("binvbatch") + private Integer binvbatch; + @JsonProperty("jobid") + private String jobid; + @JsonProperty("stg_location") + private String stg_location; + @JsonProperty("groupNum") + private String groupNum; + + + } + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/domain/DeliveryNoticeItemVo.java b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/DeliveryNoticeItemVo.java index 8fd3ecd..24f52b9 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/domain/DeliveryNoticeItemVo.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/DeliveryNoticeItemVo.java @@ -4,6 +4,9 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; +import org.w3c.dom.stylesheets.LinkStyle; + +import java.util.List; /** * 出入库通知单-子表接收对象 @@ -42,7 +45,38 @@ public class DeliveryNoticeItemVo { /** 备注 */ private String remark; + private List locations; + /**货位*/ private String area; - + /**托盘*/ private String location; + + private String areaBefore; + + private String locationBefore; + /** 项目号 */ + private String projectNo; + /** + * erp子表主键 + ***/ + private String sourceLineId; + /** + * 条码号 + ***/ + private String barCode; + /** + * 是否批次管理 + **/ + private String isBatchManage; + + /**旧项目号**/ + private String oldProjectNo; + /**组件号**/ + private String groupNum; + + + /**存放地点 1 立库 2平库*/ + private String stg_location; + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/domain/DeliveryNoticeVo.java b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/DeliveryNoticeVo.java index f11d15f..88f545e 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/domain/DeliveryNoticeVo.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/DeliveryNoticeVo.java @@ -49,6 +49,17 @@ public class DeliveryNoticeVo { private String warehouseId; /** 备注 */ private String remark; + /** 配送终点 */ + private String destination; + /** 领料车间 */ + private String workshop; + + + private String companyShortName; + /** 账套号**/ + private String accountSetNo; /** 子表明细列表 */ + + private List detailList; } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/domain/LocationDetail.java b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/LocationDetail.java new file mode 100644 index 0000000..8b4fc4a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/LocationDetail.java @@ -0,0 +1,44 @@ +package com.ruoyi.api.domain; + +public class LocationDetail { + + private String locationNo; + + private String areaNo; + + private String quantity; + + private String lotNo; + + public String getLocationNo() { + return locationNo; + } + + public void setLocationNo(String locationNo) { + this.locationNo = locationNo; + } + + public String getAreaNo() { + return areaNo; + } + + public void setAreaNo(String areaNo) { + this.areaNo = areaNo; + } + + public String getQuantity() { + return quantity; + } + + public void setQuantity(String quantity) { + this.quantity = quantity; + } + + public String getLotNo() { + return lotNo; + } + + public void setLotNo(String lotNo) { + this.lotNo = lotNo; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/domain/RequestEnter.java b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/RequestEnter.java index 044d7dd..8638acf 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/domain/RequestEnter.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/RequestEnter.java @@ -20,4 +20,8 @@ public class RequestEnter { private String type; private String flag; + private String taskNo; + private String deviceCode; + private String code; + private String errorCode; } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/domain/WmsJobRequest.java b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/WmsJobRequest.java index 4b0ec5f..079124f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/domain/WmsJobRequest.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/WmsJobRequest.java @@ -24,4 +24,6 @@ public class WmsJobRequest { private String positionCode2; //任务id private String jobId; + //线体号 + private String code; } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/controller/MoveMsgController.java b/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/controller/MoveMsgController.java new file mode 100644 index 0000000..69b3893 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/controller/MoveMsgController.java @@ -0,0 +1,104 @@ +package com.ruoyi.api.moveMsg.controller; + +import java.util.List; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.api.moveMsg.domain.MoveMsg; +import com.ruoyi.api.moveMsg.service.IMoveMsgService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 移库信息回传Controller + * + * @author ruoyi + * @date 2026-01-29 + */ +@RestController +@RequestMapping("/api/moveMsg") +public class MoveMsgController extends BaseController +{ + @Autowired + private IMoveMsgService moveMsgService; + + /** + * 查询移库信息回传列表 + */ + @PreAuthorize("@ss.hasPermi('api:moveMsg:list')") + @GetMapping("/list") + public TableDataInfo list(MoveMsg moveMsg) + { + startPage(); + List list = moveMsgService.selectMoveMsgList(moveMsg); + return getDataTable(list); + } + + /** + * 导出移库信息回传列表 + */ + @PreAuthorize("@ss.hasPermi('api:moveMsg:export')") + @Log(title = "移库信息回传", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, MoveMsg moveMsg) + { + List list = moveMsgService.selectMoveMsgList(moveMsg); + ExcelUtil util = new ExcelUtil(MoveMsg.class); + util.exportExcel(response, list, "移库信息回传数据"); + } + + /** + * 获取移库信息回传详细信息 + */ + @PreAuthorize("@ss.hasPermi('api:moveMsg:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) + { + return success(moveMsgService.selectMoveMsgById(id)); + } + + /** + * 新增移库信息回传 + */ + @PreAuthorize("@ss.hasPermi('api:moveMsg:add')") + @Log(title = "移库信息回传", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody MoveMsg moveMsg) + { + return toAjax(moveMsgService.insertMoveMsg(moveMsg)); + } + + /** + * 修改移库信息回传 + */ + @PreAuthorize("@ss.hasPermi('api:moveMsg:edit')") + @Log(title = "移库信息回传", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody MoveMsg moveMsg) + { + return toAjax(moveMsgService.updateMoveMsg(moveMsg)); + } + + /** + * 删除移库信息回传 + */ + @PreAuthorize("@ss.hasPermi('api:moveMsg:remove')") + @Log(title = "移库信息回传", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable String[] ids) + { + return toAjax(moveMsgService.deleteMoveMsgByIds(ids)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/domain/MoveMsg.java b/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/domain/MoveMsg.java new file mode 100644 index 0000000..fc8ccad --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/domain/MoveMsg.java @@ -0,0 +1,202 @@ +package com.ruoyi.api.moveMsg.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; + +/** + * 移库信息回传对象 move_msg + * + * @author ruoyi + * @date 2026-01-29 + */ +public class MoveMsg extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 序号 */ + private String id; + + /** 托盘条码 */ + @Excel(name = "托盘条码") + private String trayCode; + + /** 原货位 */ + @Excel(name = "原货位") + private String oldSpace; + + /** 新货位 */ + @Excel(name = "新货位") + private String newSpace; + + /** 状态 */ + @Excel(name = "状态") + private String status; + + /** 发送时间 */ + @Excel(name = "发送时间") + private String sendTime; + + /** 信息 */ + @Excel(name = "信息") + private String msg; + + /** 备用 */ + @Excel(name = "备用") + private String spare1; + + /** 备用 */ + @Excel(name = "备用") + private String spare2; + + /** 备用 */ + @Excel(name = "备用") + private String spare3; + + /** 备用 */ + @Excel(name = "备用") + private String spare4; + + /** 备用 */ + @Excel(name = "备用") + private String spare5; + + public void setId(String id) + { + this.id = id; + } + + public String getId() + { + return id; + } + + public void setTrayCode(String trayCode) + { + this.trayCode = trayCode; + } + + public String getTrayCode() + { + return trayCode; + } + + public void setOldSpace(String oldSpace) + { + this.oldSpace = oldSpace; + } + + public String getOldSpace() + { + return oldSpace; + } + + public void setNewSpace(String newSpace) + { + this.newSpace = newSpace; + } + + public String getNewSpace() + { + return newSpace; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + + public void setSendTime(String sendTime) + { + this.sendTime = sendTime; + } + + public String getSendTime() + { + return sendTime; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public String getMsg() + { + return msg; + } + + public void setSpare1(String spare1) + { + this.spare1 = spare1; + } + + public String getSpare1() + { + return spare1; + } + + public void setSpare2(String spare2) + { + this.spare2 = spare2; + } + + public String getSpare2() + { + return spare2; + } + + public void setSpare3(String spare3) + { + this.spare3 = spare3; + } + + public String getSpare3() + { + return spare3; + } + + public void setSpare4(String spare4) + { + this.spare4 = spare4; + } + + public String getSpare4() + { + return spare4; + } + + public void setSpare5(String spare5) + { + this.spare5 = spare5; + } + + public String getSpare5() + { + return spare5; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("trayCode", getTrayCode()) + .append("oldSpace", getOldSpace()) + .append("newSpace", getNewSpace()) + .append("status", getStatus()) + .append("sendTime", getSendTime()) + .append("msg", getMsg()) + .append("spare1", getSpare1()) + .append("spare2", getSpare2()) + .append("spare3", getSpare3()) + .append("spare4", getSpare4()) + .append("spare5", getSpare5()) + .toString(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/mapper/MoveMsgMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/mapper/MoveMsgMapper.java new file mode 100644 index 0000000..80a588b --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/mapper/MoveMsgMapper.java @@ -0,0 +1,61 @@ +package com.ruoyi.api.moveMsg.mapper; + +import java.util.List; +import com.ruoyi.api.moveMsg.domain.MoveMsg; + +/** + * 移库信息回传Mapper接口 + * + * @author ruoyi + * @date 2026-01-29 + */ +public interface MoveMsgMapper +{ + /** + * 查询移库信息回传 + * + * @param id 移库信息回传主键 + * @return 移库信息回传 + */ + public MoveMsg selectMoveMsgById(String id); + + /** + * 查询移库信息回传列表 + * + * @param moveMsg 移库信息回传 + * @return 移库信息回传集合 + */ + public List selectMoveMsgList(MoveMsg moveMsg); + + /** + * 新增移库信息回传 + * + * @param moveMsg 移库信息回传 + * @return 结果 + */ + public int insertMoveMsg(MoveMsg moveMsg); + + /** + * 修改移库信息回传 + * + * @param moveMsg 移库信息回传 + * @return 结果 + */ + public int updateMoveMsg(MoveMsg moveMsg); + + /** + * 删除移库信息回传 + * + * @param id 移库信息回传主键 + * @return 结果 + */ + public int deleteMoveMsgById(String id); + + /** + * 批量删除移库信息回传 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteMoveMsgByIds(String[] ids); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/service/IMoveMsgService.java b/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/service/IMoveMsgService.java new file mode 100644 index 0000000..23c4ee9 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/service/IMoveMsgService.java @@ -0,0 +1,61 @@ +package com.ruoyi.api.moveMsg.service; + +import java.util.List; +import com.ruoyi.api.moveMsg.domain.MoveMsg; + +/** + * 移库信息回传Service接口 + * + * @author ruoyi + * @date 2026-01-29 + */ +public interface IMoveMsgService +{ + /** + * 查询移库信息回传 + * + * @param id 移库信息回传主键 + * @return 移库信息回传 + */ + public MoveMsg selectMoveMsgById(String id); + + /** + * 查询移库信息回传列表 + * + * @param moveMsg 移库信息回传 + * @return 移库信息回传集合 + */ + public List selectMoveMsgList(MoveMsg moveMsg); + + /** + * 新增移库信息回传 + * + * @param moveMsg 移库信息回传 + * @return 结果 + */ + public int insertMoveMsg(MoveMsg moveMsg); + + /** + * 修改移库信息回传 + * + * @param moveMsg 移库信息回传 + * @return 结果 + */ + public int updateMoveMsg(MoveMsg moveMsg); + + /** + * 批量删除移库信息回传 + * + * @param ids 需要删除的移库信息回传主键集合 + * @return 结果 + */ + public int deleteMoveMsgByIds(String[] ids); + + /** + * 删除移库信息回传信息 + * + * @param id 移库信息回传主键 + * @return 结果 + */ + public int deleteMoveMsgById(String id); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/service/impl/MoveMsgServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/service/impl/MoveMsgServiceImpl.java new file mode 100644 index 0000000..0334df5 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/moveMsg/service/impl/MoveMsgServiceImpl.java @@ -0,0 +1,93 @@ +package com.ruoyi.api.moveMsg.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.api.moveMsg.mapper.MoveMsgMapper; +import com.ruoyi.api.moveMsg.domain.MoveMsg; +import com.ruoyi.api.moveMsg.service.IMoveMsgService; + +/** + * 移库信息回传Service业务层处理 + * + * @author ruoyi + * @date 2026-01-29 + */ +@Service +public class MoveMsgServiceImpl implements IMoveMsgService +{ + @Autowired + private MoveMsgMapper moveMsgMapper; + + /** + * 查询移库信息回传 + * + * @param id 移库信息回传主键 + * @return 移库信息回传 + */ + @Override + public MoveMsg selectMoveMsgById(String id) + { + return moveMsgMapper.selectMoveMsgById(id); + } + + /** + * 查询移库信息回传列表 + * + * @param moveMsg 移库信息回传 + * @return 移库信息回传 + */ + @Override + public List selectMoveMsgList(MoveMsg moveMsg) + { + return moveMsgMapper.selectMoveMsgList(moveMsg); + } + + /** + * 新增移库信息回传 + * + * @param moveMsg 移库信息回传 + * @return 结果 + */ + @Override + public int insertMoveMsg(MoveMsg moveMsg) + { + return moveMsgMapper.insertMoveMsg(moveMsg); + } + + /** + * 修改移库信息回传 + * + * @param moveMsg 移库信息回传 + * @return 结果 + */ + @Override + public int updateMoveMsg(MoveMsg moveMsg) + { + return moveMsgMapper.updateMoveMsg(moveMsg); + } + + /** + * 批量删除移库信息回传 + * + * @param ids 需要删除的移库信息回传主键 + * @return 结果 + */ + @Override + public int deleteMoveMsgByIds(String[] ids) + { + return moveMsgMapper.deleteMoveMsgByIds(ids); + } + + /** + * 删除移库信息回传信息 + * + * @param id 移库信息回传主键 + * @return 结果 + */ + @Override + public int deleteMoveMsgById(String id) + { + return moveMsgMapper.deleteMoveMsgById(id); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/service/IToErpService.java b/ruoyi-admin/src/main/java/com/ruoyi/api/service/IToErpService.java index f140fc6..8519c47 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/service/IToErpService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/service/IToErpService.java @@ -1,6 +1,7 @@ package com.ruoyi.api.service; import com.ruoyi.api.domain.DeliveryNoticeVo; +import com.ruoyi.api.moveMsg.domain.MoveMsg; import com.ruoyi.bas.BasProduct.domain.BasProduct; import com.ruoyi.common.core.domain.AjaxResult; @@ -16,5 +17,13 @@ public interface IToErpService { void callbackoutDeliveryNotice(); + void moveCargoSpace(); + AjaxResult createWorkshopInboundOrder(BasProduct basProduct); + + void callbackInDeliveryNoticeNew(); + + void callbackDeliveryOutNoticeNew(); + + void callbackDeliveryOutNoticeNews(); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/service/IToWmsService.java b/ruoyi-admin/src/main/java/com/ruoyi/api/service/IToWmsService.java index f41f6da..06a32d8 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/service/IToWmsService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/service/IToWmsService.java @@ -59,4 +59,6 @@ public interface IToWmsService { * 作废物料 */ AjaxResult InvalidProduct(ErpProduct erpProduct); + + AjaxResult requestEnterByTaskNo(RequestEnter requestEnter); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/service/ITwinService.java b/ruoyi-admin/src/main/java/com/ruoyi/api/service/ITwinService.java index 1a7ff85..ae430e2 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/service/ITwinService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/service/ITwinService.java @@ -4,5 +4,7 @@ import java.util.Map; public interface ITwinService { Map getStockListOverview(); + Map getCargo(String cargoSpaceName); + Map getTaskCargo(String taskNo); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToErpServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToErpServiceImpl.java index 0841b34..01d44e7 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToErpServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToErpServiceImpl.java @@ -1,8 +1,13 @@ package com.ruoyi.api.service.impl; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; +import com.ruoyi.api.controller.BatchNoGenerator; import com.ruoyi.api.domain.*; +import com.ruoyi.api.moveMsg.domain.MoveMsg; +import com.ruoyi.api.moveMsg.service.IMoveMsgService; import com.ruoyi.api.service.IToErpService; import com.ruoyi.bas.BasProduct.domain.BasProduct; import com.ruoyi.bas.basJobId.service.IBasJobIdService; @@ -27,10 +32,17 @@ import com.ruoyi.log.domain.RequestLog; import com.ruoyi.log.service.IRequestLogService; import com.ruoyi.out.outStockout.domain.OutStockout; import com.ruoyi.out.outStockout.service.IOutStockoutService; +import com.ruoyi.out.outStockoutBack.domain.OutStockoutBack; +import com.ruoyi.out.outStockoutBack.mapper.OutStockoutBackMapper; +import com.ruoyi.out.outStockoutBack.service.IOutStockoutBackService; import com.ruoyi.out.outStockoutDetail.domain.OutStockoutDetail; import com.ruoyi.out.outStockoutDetail.service.IOutStockoutDetailService; import com.ruoyi.out.outStockoutDetail.mapper.OutStockoutDetailMapper; import com.ruoyi.out.outStockout.mapper.OutStockoutMapper; +import com.ruoyi.out.outStockoutDetailBack.domain.OutStockoutDetailBack; +import com.ruoyi.out.outStockoutDetailBack.service.IOutStockoutDetailBackService; +import com.ruoyi.stock.stock.domain.BasStock; +import com.ruoyi.stock.stock.service.IBasStockService; import io.swagger.v3.oas.models.security.SecurityScheme; import org.apache.pdfbox.pdmodel.interactive.viewerpreferences.PDViewerPreferences; import org.springframework.beans.BeanUtils; @@ -38,10 +50,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.math.BigDecimal; +import java.util.Map; +import java.util.stream.Collectors; + +import static com.ruoyi.framework.datasource.DynamicDataSourceContextHolder.log; /** * 作业统计 Service 实现 @@ -55,9 +72,10 @@ public class ToErpServiceImpl implements IToErpService { private IMydoJobService mydoJobService; @Autowired private IMydoJobDetailService mydoJobDetailService; - @Autowired - private IBasJobIdService basJobIdService; + private IBasJobIdService iBasJobIdService; + @Autowired + private IBasJobIdService basJobIdService; @Autowired private IRequestLogService requestLogService; @@ -79,13 +97,24 @@ public class ToErpServiceImpl implements IToErpService { private IInStockinBackService inStockinBackService; @Autowired private IInStockinDetailBackService inStockinDetailBackService; + @Autowired + private IMoveMsgService moveMsgService; + + @Autowired + private IBasStockService basStockService; + @Autowired + private IOutStockoutBackService outStockoutBackService; + + @Autowired + private IOutStockoutDetailBackService outStockoutDetailBackService; private static final String TO_ERP_URL = "http://192.168.1.100:8080/api/"; //todo 需要调试 - private static final String WORKSHOP_INBOUND_ORDER_URL = TO_ERP_URL+"TRANSACTION_DOC"; + private static final String WORKSHOP_INBOUND_ORDER_URL = TO_ERP_URL + "TRANSACTION_DOC"; //todo 需要调试 - private static final String OTHER_IN_OUTBOUND_ORDER_URL = TO_ERP_URL+"WIP_TRANSFER_DOC"; + private static final String OTHER_IN_OUTBOUND_ORDER_URL = TO_ERP_URL + "WIP_TRANSFER_DOC"; + /** * 处理送货通知单的业务逻辑 * 根据单据类型和操作类型进行入库单或出库单的增删改操作 @@ -93,24 +122,269 @@ public class ToErpServiceImpl implements IToErpService { * @param deliveryNoticeVo 送货通知单数据对象,包含单据基本信息和明细列表 * @return AjaxResult 操作结果,包含成功或错误信息 */ +// @Override +// @Transactional(rollbackFor = Exception.class) +// public AjaxResult receiveDeliveryNotice(DeliveryNoticeVo deliveryNoticeVo) { +// +// if (deliveryNoticeVo == null || deliveryNoticeVo.getDetailList() == null || deliveryNoticeVo.getDetailList().isEmpty()) { +// return AjaxResult.error("单据或明细不能为空"); +// } +// String billType = deliveryNoticeVo.getBillType(); +// String opType = deliveryNoticeVo.getOpType(); +//// String status = deliveryNoticeVo.getStatus(); +// int type = 0; +// try { +// type = Integer.parseInt(billType); +// } catch (Exception ignored) { +// } +// +// // 处理入库单相关操作(单据类型1-4) +// if (type >= 1 && type <= 4) { +// InStockin param = new InStockin(); +// param.setErpBill(deliveryNoticeVo.getBillNo()); +// List existList = inStockinService.selectInStockinListApi(param); +// InStockin exist = (existList != null && !existList.isEmpty()) ? existList.get(0) : null; +// +// // 删除操作(操作类型3) +// if ("3".equals(opType)) { +// if (exist == null) { +// return AjaxResult.error("单据不存在"); +// } +// if ("3".equals(exist.getStatus())) { +// return AjaxResult.error("单据已执行,禁止删除"); +// } +// if (exist.getStockinGuid() != null) { +// inStockinDetailService.deleteInStockinDetailByStockinGuid(exist.getStockinGuid()); +// inStockinService.deleteInStockinByStockinGuid(exist.getStockinGuid()); +// } +// +// return AjaxResult.success(); +// } +// +// // 新增或修改操作(操作类型1或2) +// if ("2".equals(opType) || "1".equals(opType)) { +// if ("2".equals(opType) && exist == null) { +// return AjaxResult.error("单据不存在,无法修改"); +// } +// if ("1".equals(opType) && exist != null) { +// return AjaxResult.error("单据已存在,请勿重复添加"); +// } +// if (exist != null && "3".equals(exist.getStatus()) && "2".equals(opType)) { +// return AjaxResult.error("单据已执行,禁止修改"); +// } +// InStockin inStockin = exist != null ? exist : new InStockin(); +// if (exist == null) { +// inStockin.setStockinGuid(UUID.randomUUID().toString()); +// } +// String rkdId = iBasJobIdService.getJobId("RKD"); +// +// inStockin.setStockinId(rkdId); +// inStockin.setInType(deliveryNoticeVo.getBillType()); +// inStockin.setCreateDate(deliveryNoticeVo.getBillDate()); +// inStockin.setCreateManId(deliveryNoticeVo.getCreateMan()); +// inStockin.setStatus("2"); +// inStockin.setWarehouseId(deliveryNoticeVo.getWarehouseId()); +// inStockin.setErpBill(deliveryNoticeVo.getBillNo()); +// inStockin.setStockSource("1"); +// inStockin.setDepartmentNo(deliveryNoticeVo.getProjectNo());//项目号 +// inStockin.setSupplierNo(deliveryNoticeVo.getCustomerId());//供应商编码 +// inStockin.setClassNo(deliveryNoticeVo.getCustomerName());//供应商名称 +// inStockin.setSpare1(deliveryNoticeVo.getContractNo());//合同号 +// inStockin.setSpare2(deliveryNoticeVo.getSalesOrderNo());//销售订单号 +// inStockin.setSpare3(deliveryNoticeVo.getApproveDate());//审核时间 +// inStockin.setSpare4(deliveryNoticeVo.getApproveMan());//审核人 +// inStockin.setSpare5(deliveryNoticeVo.getRemark()); +// inStockin.setCompanyShortName(deliveryNoticeVo.getCompanyShortName()); +// inStockin.setAccountSetNo(deliveryNoticeVo.getAccountSetNo()); +// if (exist == null) { +// inStockinService.insertInStockin(inStockin); +// } else { +// inStockinService.updateInStockin(inStockin); +// inStockinDetailService.deleteInStockinDetailByStockinGuid(inStockin.getStockinGuid()); +// } +// List items = deliveryNoticeVo.getDetailList(); +// +// int a = 0; +// for (DeliveryNoticeItemVo item : items) { +// a += 1; +// InStockinDetail detail = new InStockinDetail(); +// detail.setStockinGuid(inStockin.getStockinGuid()); +// detail.setStockinDetailId(item.getBarCode()); +// detail.setStockinId(inStockin.getStockinId()); +// detail.setProductId(item.getInventoryCode()); +// detail.setProductName(item.getInventoryName()); +// detail.setSpec(item.getSpecModel()); +// detail.setUnit(item.getUnit()); +// detail.setQuantity(item.getQuantity()); +// if (item.getIsBatchManage().equals("1") && (item.getLotNo().equals("") || item.getLotNo() == null)) { +// // 获取流水号 +// detail.setLotNo(BatchNoGenerator.generateBatchNo()); +// } else { +// detail.setLotNo(item.getLotNo()); +// } +// detail.setSpare1(item.getLevelRelation()); +// detail.setSpare2(item.getUpperMaterial()); +// detail.setSpare3(item.getTopMaterial()); +// detail.setSpare4(item.getProjectNo()); +// detail.setSpare6(item.getLineNo()); +// detail.setRemark(item.getRemark()); +// detail.setAssignNum("0"); +// detail.setScanNum("0"); +// detail.setSourceLineId(item.getSourceLineId()); +// detail.setBarCode(item.getBarCode()); +// detail.setIsBatchManage(item.getIsBatchManage()); +// detail.setOldProjectNo(item.getOldProjectNo()); +// detail.setCargoNo(item.getGroupNum()); +// inStockinDetailService.insertInStockinDetail(detail); +// +// } +// +// return AjaxResult.success(); +// } +// } +// // 处理出库单相关操作(单据类型5-7) +// else if (type >= 5 && type <= 7) { +// OutStockout param = new OutStockout(); +// param.setErpStockoutId(deliveryNoticeVo.getBillNo()); +// List outList = outStockoutService.selectOutStockoutList(param); +// OutStockout exist = (outList != null && !outList.isEmpty()) ? outList.get(0) : null; +// +// // 删除操作(操作类型3) +// if ("3".equals(opType)) { +// if (exist == null) { +// return AjaxResult.error("单据不存在"); +// } +// if ("3".equals(exist.getStatus())) { +// return AjaxResult.error("单据已执行,禁止删除"); +// } +// OutStockoutDetail outStockoutDetail = new OutStockoutDetail(); +// outStockoutDetail.setStockoutId(deliveryNoticeVo.getBillNo()); +// List details = outStockoutDetailService.selectOutStockoutDetailList(outStockoutDetail); +// if (details != null && !details.isEmpty()) { +// String[] ids = details.stream().map(OutStockoutDetail::getStockoutDetailId).toArray(String[]::new); +// outStockoutDetailService.deleteOutStockoutDetailByStockoutDetailIds(ids); +// } +// outStockoutService.deleteOutStockoutByStockoutGuid(exist.getStockoutGuid()); +// return AjaxResult.success(); +// } +// +// // 新增或修改操作(操作类型1或2) +// if ("2".equals(opType) || "1".equals(opType)) { +// if ("2".equals(opType) && exist == null) { +// return AjaxResult.error("单据不存在,无法修改"); +// } +// if ("1".equals(opType) && exist != null) { +// return AjaxResult.error("单据已存在,请勿重复添加"); +// } +// if (exist != null && "3".equals(exist.getStatus()) && "2".equals(opType)) { +// return AjaxResult.error("单据已执行,禁止修改"); +// } +// OutStockout out = exist != null ? exist : new OutStockout(); +// +// if (exist == null) { +// out.setStockoutGuid(UUID.randomUUID().toString()); +// } +// String ckdId = iBasJobIdService.getJobId("CKD"); +// out.setStockoutId(ckdId); +// out.setOutType(deliveryNoticeVo.getBillType()); +// out.setCreateDate(deliveryNoticeVo.getBillDate()); +// out.setErpStockoutId(deliveryNoticeVo.getBillNo()); +// out.setCreateManId(deliveryNoticeVo.getCreateMan()); +// out.setStatus("2"); +// out.setWarehouseId(deliveryNoticeVo.getWarehouseId()); +// out.setStockoutSource("1"); +//// out.setSpare6(deliveryNoticeVo.getOutType()); +// out.setSpare6("1"); +// out.setCarNumber(deliveryNoticeVo.getIsProjectOut()); +// out.setDepartmentNo(deliveryNoticeVo.getProjectNo()); +// out.setCustomerNo(deliveryNoticeVo.getCustomerId()); +// out.setClassNowId(deliveryNoticeVo.getCustomerName()); +// out.setSpare1(deliveryNoticeVo.getContractNo());//合同号 +// out.setSpare2(deliveryNoticeVo.getSalesOrderNo());//销售订单号 +// out.setSpare3(deliveryNoticeVo.getApproveDate());//审核时间 +// out.setSpare4(deliveryNoticeVo.getApproveMan());//审核人 +// out.setSpare5(deliveryNoticeVo.getRemark()); +// out.setSpare7(deliveryNoticeVo.getDestination()); +// //手动设置出库类型为2 这样会赋值 in_or_out 21 +// out.setSpare8("2"); +// out.setCompanyShortName(deliveryNoticeVo.getCompanyShortName()); +// out.setAccountSetNo(deliveryNoticeVo.getAccountSetNo()); +// +// if (exist == null) { +// outStockoutService.insertOutStockout(out); +// } else { +// outStockoutService.updateOutStockout(out); +// OutStockoutDetail q2 = new OutStockoutDetail(); +// q2.setStockoutId(deliveryNoticeVo.getBillNo()); +// List oldDetails = outStockoutDetailService.selectOutStockoutDetailList(q2); +// if (oldDetails != null && !oldDetails.isEmpty()) { +// String[] ids = oldDetails.stream().map(OutStockoutDetail::getStockoutDetailId).toArray(String[]::new); +// outStockoutDetailService.deleteOutStockoutDetailByStockoutDetailIds(ids); +// } +// } +// int i = 0; +// for (DeliveryNoticeItemVo item : deliveryNoticeVo.getDetailList()) { +// OutStockoutDetail d = new OutStockoutDetail(); +// i += 1; +// d.setStockoutDetailId(out.getStockoutId() + "-" + i); +// d.setStockoutGuid(out.getStockoutGuid()); +// d.setStockoutId(out.getStockoutId()); +// d.setProductId(item.getInventoryCode()); +// d.setProductName(item.getInventoryName()); +// d.setLotNo(item.getLotNo()); +// d.setSpec(item.getSpecModel()); +// d.setUnit(item.getUnit()); +// d.setSpare1(item.getLevelRelation()); +// d.setSpare2(item.getUpperMaterial()); +// d.setSpare3(item.getTopMaterial()); +// d.setSpare4(item.getProjectNo()); +// d.setSpare6(item.getLineNo()); +// d.setRemark(item.getRemark()); +// d.setSourceLineId(item.getSourceLineId()); +// d.setCargoNo(item.getGroupNum()); +// d.setBarCode(item.getBarCode()); +// d.setIsBatchManage(item.getIsBatchManage()); +// d.setOldProjectNo(item.getOldProjectNo()); +// //d.setSpare8(deliveryNoticeVo.getDestination()); +// +// +// try { +// d.setQuantity(new BigDecimal(item.getQuantity())); +// d.setAllotQuantity(BigDecimal.ZERO); +// d.setAssignNum(BigDecimal.ZERO); +// } catch (Exception e) { +// d.setQuantity(BigDecimal.ZERO); +// } +// outStockoutDetailService.insertOutStockoutDetail(d); +// +// } +// return AjaxResult.success(); +// } +// } +// return AjaxResult.error("不支持的单据类型或操作类型"); +// +// } @Override @Transactional(rollbackFor = Exception.class) public AjaxResult receiveDeliveryNotice(DeliveryNoticeVo deliveryNoticeVo) { - - if (deliveryNoticeVo == null || deliveryNoticeVo.getDetailList() == null || deliveryNoticeVo.getDetailList().isEmpty()){ + if (deliveryNoticeVo == null || deliveryNoticeVo.getDetailList() == null || deliveryNoticeVo.getDetailList().isEmpty()) { return AjaxResult.error("单据或明细不能为空"); } String billType = deliveryNoticeVo.getBillType(); String opType = deliveryNoticeVo.getOpType(); -// String status = deliveryNoticeVo.getStatus(); int type = 0; - try { type = Integer.parseInt(billType); } catch (Exception ignored) {} + try { + type = Integer.parseInt(billType); + } catch (Exception ignored) { + } - // 处理入库单相关操作(单据类型1-4) + // ===================== 入库单 1-4 逻辑完全不变 ===================== if (type >= 1 && type <= 4) { InStockin param = new InStockin(); - param.setStockinId(deliveryNoticeVo.getBillNo()); - List existList = inStockinService.selectInStockinListApi(param); + param.setErpBill(deliveryNoticeVo.getBillNo()); + param.setAccountSetNo(deliveryNoticeVo.getAccountSetNo()); + List existList = inStockinService.selectInStockinListBill(param); +// List existList = inStockinService.selectInStockinListApi(param); InStockin exist = (existList != null && !existList.isEmpty()) ? existList.get(0) : null; // 删除操作(操作类型3) @@ -125,7 +399,6 @@ public class ToErpServiceImpl implements IToErpService { inStockinDetailService.deleteInStockinDetailByStockinGuid(exist.getStockinGuid()); inStockinService.deleteInStockinByStockinGuid(exist.getStockinGuid()); } - return AjaxResult.success(); } @@ -134,7 +407,7 @@ public class ToErpServiceImpl implements IToErpService { if ("2".equals(opType) && exist == null) { return AjaxResult.error("单据不存在,无法修改"); } - if("1".equals(opType) && exist != null){ + if ("1".equals(opType) && exist != null) { return AjaxResult.error("单据已存在,请勿重复添加"); } if (exist != null && "3".equals(exist.getStatus()) && "2".equals(opType)) { @@ -144,22 +417,27 @@ public class ToErpServiceImpl implements IToErpService { if (exist == null) { inStockin.setStockinGuid(UUID.randomUUID().toString()); } - inStockin.setStockinId(deliveryNoticeVo.getBillNo()); + String rkdId = iBasJobIdService.getJobId("RKD"); + + inStockin.setStockinId(rkdId); inStockin.setInType(deliveryNoticeVo.getBillType()); inStockin.setCreateDate(deliveryNoticeVo.getBillDate()); inStockin.setCreateManId(deliveryNoticeVo.getCreateMan()); - inStockin.setStatus("1"); + inStockin.setStatus("2"); inStockin.setWarehouseId(deliveryNoticeVo.getWarehouseId()); -// inStockin.setErpBill(deliveryNoticeVo.getBillNo()); + inStockin.setErpBill(deliveryNoticeVo.getBillNo()); inStockin.setStockSource("1"); - inStockin.setDepartmentNo(deliveryNoticeVo.getProjectNo());//项目号 - inStockin.setSupplierNo(deliveryNoticeVo.getCustomerId());//供应商编码 - inStockin.setClassNo(deliveryNoticeVo.getCustomerName());//供应商名称 - inStockin.setSpare1(deliveryNoticeVo.getContractNo());//合同号 - inStockin.setSpare2(deliveryNoticeVo.getSalesOrderNo());//销售订单号 - inStockin.setSpare3(deliveryNoticeVo.getApproveDate());//审核时间 - inStockin.setSpare4(deliveryNoticeVo.getApproveMan());//审核人 + inStockin.setDepartmentNo(deliveryNoticeVo.getProjectNo()); + inStockin.setSupplierNo(deliveryNoticeVo.getCustomerId()); + inStockin.setClassNo(deliveryNoticeVo.getCustomerName()); + inStockin.setSpare1(deliveryNoticeVo.getContractNo()); + inStockin.setSpare2(deliveryNoticeVo.getSalesOrderNo()); + inStockin.setSpare3(deliveryNoticeVo.getApproveDate()); + inStockin.setSpare4(deliveryNoticeVo.getApproveMan()); inStockin.setSpare5(deliveryNoticeVo.getRemark()); + inStockin.setCompanyShortName(deliveryNoticeVo.getCompanyShortName()); + inStockin.setAccountSetNo(deliveryNoticeVo.getAccountSetNo()); + if (exist == null) { inStockinService.insertInStockin(inStockin); } else { @@ -167,41 +445,52 @@ public class ToErpServiceImpl implements IToErpService { inStockinDetailService.deleteInStockinDetailByStockinGuid(inStockin.getStockinGuid()); } List items = deliveryNoticeVo.getDetailList(); - - + int a = 0; for (DeliveryNoticeItemVo item : items) { + a += 1; InStockinDetail detail = new InStockinDetail(); detail.setStockinGuid(inStockin.getStockinGuid()); - detail.setStockinDetailId(inStockin.getStockinId()+"-"+item.getLineNo()); + detail.setStockinDetailId(inStockin.getStockinId() + '-' + a); detail.setStockinId(inStockin.getStockinId()); detail.setProductId(item.getInventoryCode()); detail.setProductName(item.getInventoryName()); detail.setSpec(item.getSpecModel()); detail.setUnit(item.getUnit()); detail.setQuantity(item.getQuantity()); - detail.setLotNo(item.getLotNo()); + if (item.getIsBatchManage().equals("1") && (item.getLotNo().equals("") || item.getLotNo() == null)) { + detail.setLotNo(BatchNoGenerator.generateBatchNo()); + } else { + detail.setLotNo(item.getLotNo()); + } detail.setSpare1(item.getLevelRelation()); detail.setSpare2(item.getUpperMaterial()); detail.setSpare3(item.getTopMaterial()); + detail.setSpare4(item.getProjectNo()); detail.setSpare6(item.getLineNo()); detail.setRemark(item.getRemark()); detail.setAssignNum("0"); detail.setScanNum("0"); + detail.setSourceLineId(item.getSourceLineId()); + detail.setBarCode(item.getBarCode()); + detail.setIsBatchManage(item.getIsBatchManage()); + detail.setOldProjectNo(item.getOldProjectNo()); + detail.setCargoNo(item.getGroupNum()); inStockinDetailService.insertInStockinDetail(detail); - } - return AjaxResult.success(); } } - // 处理出库单相关操作(单据类型5-7) + + // ===================== 出库单 5-7 改造:按立库/平库分两组各1主单多明细 ===================== else if (type >= 5 && type <= 7) { OutStockout param = new OutStockout(); - param.setStockoutId(deliveryNoticeVo.getBillNo()); + param.setErpStockoutId(deliveryNoticeVo.getBillNo()); + param.setAccountSetNo(deliveryNoticeVo.getAccountSetNo()); List outList = outStockoutService.selectOutStockoutList(param); OutStockout exist = (outList != null && !outList.isEmpty()) ? outList.get(0) : null; + String billNo = deliveryNoticeVo.getBillNo(); - // 删除操作(操作类型3) + // 删除操作 不变 if ("3".equals(opType)) { if (exist == null) { return AjaxResult.error("单据不存在"); @@ -210,7 +499,7 @@ public class ToErpServiceImpl implements IToErpService { return AjaxResult.error("单据已执行,禁止删除"); } OutStockoutDetail outStockoutDetail = new OutStockoutDetail(); - outStockoutDetail.setStockoutId(deliveryNoticeVo.getBillNo()); + outStockoutDetail.setStockoutId(billNo); List details = outStockoutDetailService.selectOutStockoutDetailList(outStockoutDetail); if (details != null && !details.isEmpty()) { String[] ids = details.stream().map(OutStockoutDetail::getStockoutDetailId).toArray(String[]::new); @@ -220,114 +509,195 @@ public class ToErpServiceImpl implements IToErpService { return AjaxResult.success(); } - // 新增或修改操作(操作类型1或2) + // 新增/修改 if ("2".equals(opType) || "1".equals(opType)) { if ("2".equals(opType) && exist == null) { return AjaxResult.error("单据不存在,无法修改"); } - if ("1".equals(opType) && exist != null){ + if ("1".equals(opType) && exist != null) { return AjaxResult.error("单据已存在,请勿重复添加"); } - if (exist != null && "3".equals(exist.getStatus()) && "2".equals(opType) ) { + if (exist != null && "3".equals(exist.getStatus()) && "2".equals(opType)) { return AjaxResult.error("单据已执行,禁止修改"); } - OutStockout out = exist != null ? exist : new OutStockout(); - if (exist == null) { - out.setStockoutGuid(UUID.randomUUID().toString()); + List allDetail = deliveryNoticeVo.getDetailList(); + // 1. 按 stg_location 分组 + List liKuList = new ArrayList<>(); + List pingKuList = new ArrayList<>(); + for (DeliveryNoticeItemVo item : allDetail) { + String loc = item.getStg_location(); + if ("2".equals(loc)) { + pingKuList.add(item); + } else { + // 1 或空 都归立库 + liKuList.add(item); + } } - out.setStockoutId(deliveryNoticeVo.getBillNo()); - out.setOutType(deliveryNoticeVo.getBillType()); - out.setCreateDate(deliveryNoticeVo.getBillDate()); - out.setCreateManId(deliveryNoticeVo.getCreateMan()); - out.setStatus("1"); - out.setWarehouseId(deliveryNoticeVo.getWarehouseId()); - out.setStockoutSource("1"); - out.setDepartmentNo(deliveryNoticeVo.getProjectNo()); - out.setCustomerNo(deliveryNoticeVo.getCustomerId()); - out.setClassNowId(deliveryNoticeVo.getCustomerName()); - out.setSpare1(deliveryNoticeVo.getContractNo());//合同号 - out.setSpare2(deliveryNoticeVo.getSalesOrderNo());//销售订单号 - out.setSpare3(deliveryNoticeVo.getApproveDate());//审核时间 - out.setSpare4(deliveryNoticeVo.getApproveMan());//审核人 - out.setSpare5(deliveryNoticeVo.getRemark()); + + // ========== 处理立库:原有主单 + 所有立库明细 ========== + OutStockout mainOut = exist != null ? exist : new OutStockout(); + if (exist == null) { + mainOut.setStockoutGuid(UUID.randomUUID().toString()); + } + if (liKuList.size() > 0) { + String ckdId = iBasJobIdService.getJobId("CKD"); + fillOutStockout(mainOut, deliveryNoticeVo, ckdId); + } + if (exist == null) { - outStockoutService.insertOutStockout(out); + String ckdId = iBasJobIdService.getJobId("CKD"); + fillOutStockout(mainOut, deliveryNoticeVo, ckdId); + outStockoutService.insertOutStockout(mainOut); } else { - outStockoutService.updateOutStockout(out); + outStockoutService.updateOutStockouts(mainOut); + // 修改先删旧明细 OutStockoutDetail q2 = new OutStockoutDetail(); - q2.setStockoutId(deliveryNoticeVo.getBillNo()); + q2.setStockoutId(billNo); List oldDetails = outStockoutDetailService.selectOutStockoutDetailList(q2); if (oldDetails != null && !oldDetails.isEmpty()) { - String[] ids = oldDetails.stream().map(OutStockoutDetail::getStockoutDetailId).toArray(String[]::new); + String[] ids = oldDetails.stream() + .map(OutStockoutDetail::getStockoutDetailId) + .toArray(String[]::new); outStockoutDetailService.deleteOutStockoutDetailByStockoutDetailIds(ids); } } + if (liKuList.size() > 0) { + // 保存所有立库明细到主单 + saveOutDetailList(mainOut, liKuList, "1"); + } - for (DeliveryNoticeItemVo item : deliveryNoticeVo.getDetailList()) { - OutStockoutDetail d = new OutStockoutDetail(); - d.setStockoutDetailId(out.getStockoutId()+"-"+item.getLineNo()); - d.setStockoutGuid(out.getStockoutGuid()); - d.setStockoutId(out.getStockoutId()); - d.setProductId(item.getInventoryCode()); - d.setProductId(item.getInventoryCode()); - d.setLotNo(item.getLotNo()); - d.setSpec(item.getSpecModel()); - d.setUnit(item.getUnit()); - d.setSpare1(item.getLevelRelation()); - d.setSpare2(item.getUpperMaterial()); - d.setSpare3(item.getTopMaterial()); - d.setSpare6(item.getLineNo()); - d.setRemark(item.getRemark()); - - try { - d.setQuantity(new BigDecimal(item.getQuantity())); - d.setAllotQuantity(BigDecimal.ZERO); - d.setAssignNum(BigDecimal.ZERO); - } catch (Exception e) { - d.setQuantity(BigDecimal.ZERO); + // ========== 处理平库:新建一张独立主单 + 所有平库明细 ========== + if (CollUtil.isNotEmpty(pingKuList)) { + OutStockout pingKuOut = new OutStockout(); + pingKuOut.setStockoutGuid(UUID.randomUUID().toString()); + if (pingKuList.size() > 0) { + String pingCkdId = iBasJobIdService.getJobId("CKD"); + fillOutStockout(pingKuOut, deliveryNoticeVo, pingCkdId); + // 插入平库主单 + outStockoutService.insertOutStockout(pingKuOut); + log.info("平库分组生成独立出库单:{},明细条数:{}", pingCkdId, pingKuList.size()); + // 平库所有明细挂到这个新主单 + saveOutDetailList(pingKuOut, pingKuList, "2"); } - outStockoutDetailService.insertOutStockoutDetail(d); + } return AjaxResult.success(); } } return AjaxResult.error("不支持的单据类型或操作类型"); - } + /** + * 填充出库单主表公共字段 + */ + private void fillOutStockout(OutStockout out, DeliveryNoticeVo vo, String ckdId) { + out.setStockoutId(ckdId); + out.setOutType(vo.getBillType()); + out.setCreateDate(vo.getBillDate()); + out.setErpStockoutId(vo.getBillNo()); + out.setCreateManId(vo.getCreateMan()); + out.setStatus("2"); + out.setWarehouseId(vo.getWarehouseId()); + out.setStockoutSource("1"); + out.setSpare6(vo.getOutType()); // 搬运方式 1人工 2agv + out.setCarNumber(vo.getIsProjectOut()); + out.setDepartmentNo(vo.getProjectNo()); + out.setCustomerNo(vo.getCustomerId()); + out.setClassNowId(vo.getCustomerName()); + out.setSpare1(vo.getContractNo()); + out.setSpare2(vo.getSalesOrderNo()); + out.setSpare3(vo.getApproveDate()); + out.setSpare4(vo.getApproveMan()); + out.setSpare5(vo.getRemark()); + out.setSpare7(vo.getDestination()); // 配送终点 + out.setSpare8("2"); // 配送去向 1 缓存 2 线边 默认线边 + out.setCompanyShortName(vo.getCompanyShortName()); + out.setAccountSetNo(vo.getAccountSetNo()); + out.setFID(vo.getIsProjectOut()); // 是否按项目出 1是 0否 + } + + /** + * 批量保存出库明细列表 + */ + private void saveOutDetailList(OutStockout out, List detailList, String warehouseId) { + if (CollUtil.isEmpty(detailList)) { + return; + } + int i = 0; + for (DeliveryNoticeItemVo item : detailList) { + i++; + OutStockoutDetail d = new OutStockoutDetail(); + d.setStockoutDetailId(out.getStockoutId() + "-" + i); + d.setStockoutGuid(out.getStockoutGuid()); + d.setStockoutId(out.getStockoutId()); + d.setProductId(item.getInventoryCode()); + d.setProductName(item.getInventoryName()); + d.setLotNo(item.getLotNo()); + d.setSpec(item.getSpecModel()); + d.setUnit(item.getUnit()); + d.setSpare1(item.getLevelRelation()); + d.setSpare2(item.getUpperMaterial()); + d.setSpare3(item.getTopMaterial()); + d.setSpare4(item.getProjectNo()); + d.setSpare6(item.getLineNo()); + d.setRemark(item.getRemark()); + d.setSourceLineId(item.getSourceLineId()); + d.setBarCode(item.getBarCode()); + d.setIsBatchManage(item.getIsBatchManage()); + d.setOldProjectNo(item.getOldProjectNo()); + d.setProductGuid(item.getStg_location()); + d.setEntryid(item.getGroupNum()); + try { + d.setQuantity(new BigDecimal(item.getQuantity())); + d.setAllotQuantity(BigDecimal.ZERO); + d.setAssignNum(BigDecimal.ZERO); + } catch (Exception e) { + d.setQuantity(BigDecimal.ZERO); + } + outStockoutDetailService.insertOutStockoutDetail(d); + } + out.setWarehouseId(warehouseId); + outStockoutService.updateOutStockout(out); + } + @Override public void callbackInDeliveryNotice() { InStockinBack inStockin = inStockinBackService.selectTopInStockin(); + if (inStockin == null) { + return; + } DeliveryNoticeVo deliveryNoticeVo = new DeliveryNoticeVo(); deliveryNoticeVo.setBillNo(inStockin.getStockinId()); deliveryNoticeVo.setNoteBillNo(inStockin.getStockinId()); deliveryNoticeVo.setBillType(inStockin.getInType()); + deliveryNoticeVo.setOpType("1"); deliveryNoticeVo.setBillDate(inStockin.getCreateDate()); - deliveryNoticeVo.setCreateMan(inStockin.getCreateManId()); +// deliveryNoticeVo.setCreateMan(inStockin.getCreateManId()); deliveryNoticeVo.setWarehouseId(inStockin.getWarehouseId()); deliveryNoticeVo.setProjectNo(inStockin.getDepartmentNo()); deliveryNoticeVo.setCustomerId(inStockin.getSupplierNo()); deliveryNoticeVo.setCustomerName(inStockin.getClassNo()); // 对应receiveDeliveryNotice中的映射 deliveryNoticeVo.setContractNo(inStockin.getSpare1()); - deliveryNoticeVo.setSalesOrderNo(inStockin.getSpare2()); - deliveryNoticeVo.setApproveDate(inStockin.getSpare3()); - deliveryNoticeVo.setApproveMan(inStockin.getSpare4()); - deliveryNoticeVo.setRemark(inStockin.getSpare5()); +// deliveryNoticeVo.setSalesOrderNo(inStockin.getSpare2()); +// deliveryNoticeVo.setApproveDate(inStockin.getSpare3()); +// deliveryNoticeVo.setApproveMan(inStockin.getSpare4()); +// deliveryNoticeVo.setRemark(inStockin.getSpare5()); InStockinDetailBack inStockinDetailParam = new InStockinDetailBack(); inStockinDetailParam.setStockinId(inStockin.getStockinId()); List inStockinDetails = inStockinDetailBackService.selectInStockinDetailBackList(inStockinDetailParam); - + List detailList = new ArrayList<>(); if (inStockinDetails != null && !inStockinDetails.isEmpty()) { for (InStockinDetailBack detail : inStockinDetails) { DeliveryNoticeItemVo item = new DeliveryNoticeItemVo(); + item.setLineNo(detail.getStockinDetailId()); item.setNotelineNo(detail.getStockinDetailId()); item.setBillNo(detail.getStockinId()); @@ -336,29 +706,240 @@ public class ToErpServiceImpl implements IToErpService { item.setSpecModel(detail.getSpec()); item.setUnit(detail.getUnit()); item.setQuantity(detail.getAssignNum()); - item.setLotNo(detail.getLotNo()); +// item.setLotNo(detail.getLotNo()); item.setLevelRelation(detail.getSpare1()); item.setUpperMaterial(detail.getSpare2()); item.setTopMaterial(detail.getSpare3()); item.setRemark(detail.getRemark()); - item.setArea(detail.getSpare9()); - item.setLocation(detail.getSpare8()); + String[] splitArea = detail.getSpare9().split(","); + String[] splitLocation = detail.getSpare8().split(","); + String[] splitQuantity = detail.getQuantityX().split(","); + ArrayList locationDetails = new ArrayList<>(); + for (int i = 0; i < splitArea.length; i++) { + LocationDetail locationDetail = new LocationDetail(); + locationDetail.setLocationNo(splitLocation[i]); + locationDetail.setQuantity(splitQuantity[i]); + locationDetail.setAreaNo(splitArea[i]); + locationDetail.setLotNo(detail.getLotNo()); + locationDetails.add(locationDetail); + } + item.setLocations(locationDetails); + detailList.add(item); } } deliveryNoticeVo.setDetailList(detailList); - //todo 发送给erp 成功失败改状态 + String sendMsg = JSONUtil.toJsonStr(deliveryNoticeVo); + try { + //todo 发送给erp 成功失败改状态 + RequestLog requestLog = requestLogService.getRequestLog("http://192.168.188.235/app1/api?type=1&key=1", JSONUtil.toJsonStr(deliveryNoticeVo), "入库回传", "wms", "erp"); + if ("1".equals(requestLog.getIsSuccessful())) { + inStockin.setSendStatus("1"); + inStockin.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + inStockin.setMsg("成功"); + inStockinDetailParam.setSendStatus("1"); + inStockinDetailParam.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + inStockinDetailParam.setMsg("成功"); + + } else { + inStockin.setSendStatus("2"); + inStockin.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + inStockin.setMsg(requestLog.getErrorDetails()); + inStockinDetailParam.setSendStatus("2"); + inStockinDetailParam.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + inStockinDetailParam.setMsg(requestLog.getErrorDetails()); + } + inStockinBackService.updateInStockinBack(inStockin); + inStockinDetailBackService.updateInStockinDetailBack(inStockinDetailParam); + + } catch (Exception e) { + inStockin.setSendStatus("2"); + inStockin.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + inStockin.setMsg(e.getMessage()); + inStockinDetailParam.setSendStatus("2"); + inStockinDetailParam.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + inStockinDetailParam.setMsg(e.getMessage()); + inStockinBackService.updateInStockinBack(inStockin); + inStockinDetailBackService.updateInStockinDetailBack(inStockinDetailParam); + } -// return AjaxResult.success(deliveryNoticeVo); } @Override public void callbackoutDeliveryNotice() { + OutStockoutBack outStockoutBack = outStockoutBackService.selelctTopOutStockout(); + if (outStockoutBack == null) { + return; + } + DeliveryNoticeVo deliveryNoticeVo = new DeliveryNoticeVo(); + deliveryNoticeVo.setBillNo(outStockoutBack.getStockoutId()); + deliveryNoticeVo.setNoteBillNo(outStockoutBack.getStockoutId()); + deliveryNoticeVo.setBillType(outStockoutBack.getOutType()); + deliveryNoticeVo.setOpType("1"); + deliveryNoticeVo.setBillDate(outStockoutBack.getCreateDate()); + deliveryNoticeVo.setWarehouseId(outStockoutBack.getWarehouseId()); + deliveryNoticeVo.setProjectNo(outStockoutBack.getDepartmentNo()); + deliveryNoticeVo.setCustomerId(outStockoutBack.getCustomerNo()); + deliveryNoticeVo.setCustomerName(outStockoutBack.getClassNowId()); + deliveryNoticeVo.setContractNo(outStockoutBack.getSpare1()); + + OutStockoutDetailBack outStockoutDetailBack = new OutStockoutDetailBack(); + outStockoutDetailBack.setStockoutId(outStockoutBack.getStockoutId()); +// outStockoutDetailBack.setSendStatus("0"); + List outStockoutDetailBacks = outStockoutDetailBackService.selectOutStockoutDetailBackList(outStockoutDetailBack); + List detailList = new ArrayList<>(); + if (outStockoutDetailBacks != null && !outStockoutDetailBacks.isEmpty()) { + for (OutStockoutDetailBack detail : outStockoutDetailBacks) { + DeliveryNoticeItemVo item = new DeliveryNoticeItemVo(); + item.setLineNo(detail.getStockoutDetailId()); + item.setNotelineNo(detail.getStockoutDetailId()); + item.setInventoryCode(detail.getProductId()); + item.setInventoryName(detail.getProductName()); + item.setSpecModel(detail.getSpec()); + item.setUnit(detail.getUnit()); + item.setQuantity(detail.getQuantity().toString()); + item.setLevelRelation(detail.getSpare1()); + item.setUpperMaterial(detail.getSpare2()); + item.setTopMaterial(detail.getSpare3()); +// item.setLotNo(detail.getLotNo()); + item.setRemark(detail.getRemark()); +// item.setArea(detail.getSpare9()); +// item.setLocation(detail.getSpare8()); + String[] splitArea = detail.getSpare9().split(","); + String[] splitLocation = detail.getSpare8().split(","); + String[] splitQuantity = detail.getQuantityX().split(","); + String[] lotNo = new String[]{}; + if (StrUtil.isNotEmpty(detail.getLotNo())) { + lotNo = detail.getLotNo().split(","); + } + ArrayList locationDetails = new ArrayList<>(); + for (int i = 0; i < splitArea.length; i++) { + LocationDetail locationDetail = new LocationDetail(); + locationDetail.setLocationNo(splitLocation[i]); + locationDetail.setQuantity(splitQuantity[i]); + locationDetail.setAreaNo(splitArea[i]); + locationDetail.setLotNo(lotNo[i]); + locationDetails.add(locationDetail); + } + item.setLocations(locationDetails); + detailList.add(item); + } + deliveryNoticeVo.setDetailList(detailList); + } + + try { + //todo 发送给erp 成功失败改状态 + RequestLog requestLog = requestLogService.getRequestLog("http://192.168.188.235/app1/api?type=1&key=1", JSONUtil.toJsonStr(deliveryNoticeVo), "出库回传", "wms", "erp"); + if ("1".equals(requestLog.getIsSuccessful())) { + outStockoutBack.setSendStatus("1"); + outStockoutBack.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + outStockoutBack.setMsg("成功"); + outStockoutDetailBack.setSendStatus("1"); + outStockoutDetailBack.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + outStockoutDetailBack.setMsg("成功"); + + } else { + outStockoutBack.setSendStatus("2"); + outStockoutBack.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + outStockoutBack.setMsg(requestLog.getErrorDetails()); + outStockoutDetailBack.setSendStatus("2"); + outStockoutDetailBack.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + outStockoutDetailBack.setMsg(requestLog.getErrorDetails()); + } + outStockoutBackService.updateOutStockoutBack(outStockoutBack); + outStockoutDetailBackService.updateOutStockoutDetailBack(outStockoutDetailBack); + + } catch (Exception e) { + outStockoutBack.setSendStatus("2"); + outStockoutBack.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + outStockoutBack.setMsg(e.getMessage()); + outStockoutDetailBack.setSendStatus("2"); + outStockoutDetailBack.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + outStockoutDetailBack.setMsg(e.getMessage()); + outStockoutBackService.updateOutStockoutBack(outStockoutBack); + outStockoutDetailBackService.updateOutStockoutDetailBack(outStockoutDetailBack); + } + } + + @Override + public void moveCargoSpace() { + MoveMsg moveMsg1 = new MoveMsg(); + moveMsg1.setStatus("0"); + List moveMsgs = moveMsgService.selectMoveMsgList(moveMsg1); + MoveMsg moveMsg = new MoveMsg(); + if (moveMsgs.size() > 0) { + moveMsg = moveMsgs.get(0); + } else { + return; + } + + try { + BasStock basStock = new BasStock(); + basStock.setTrayCode(moveMsg.getTrayCode()); + List basStocks = basStockService.selectBasStockList(basStock); + //将basStocks按照stockinId分组 + Map> basStocksMap = basStocks.stream().collect(Collectors.groupingBy(BasStock::getStockinId)); + for (Map.Entry> entry : basStocksMap.entrySet()) { + // 获取 stockinId(键) + String stockinId = entry.getKey(); + + // 获取对应的 basStock 列表(值) + List basStockList = entry.getValue(); + DeliveryNoticeVo deliveryNoticeVo = new DeliveryNoticeVo(); + deliveryNoticeVo.setBillNo(basStockList.get(0).getStockinId()); + //deliveryNoticeVo.setNoteBillNo(basStockList.get(0).getStockinId()); + deliveryNoticeVo.setBillDate(DateUtil.formatDateTime(new Date())); + deliveryNoticeVo.setWarehouseId(basStockList.get(0).getWarehouseId()); + deliveryNoticeVo.setProjectNo(basStockList.get(0).getSpare4()); + deliveryNoticeVo.setBillType("9"); + ArrayList deliveryNoticeItemVos = new ArrayList<>(); + for (BasStock basStock1 : basStockList) { + DeliveryNoticeItemVo item = new DeliveryNoticeItemVo(); + item.setLineNo(basStock1.getStockinDetailId()); + //item.setNotelineNo(basStock1.getStockinDetailId()); + item.setInventoryCode(basStock1.getProductId()); + item.setInventoryName(basStock1.getProductName()); + item.setSpecModel(basStock1.getPower()); + item.setUnit(basStock1.getPhase()); + item.setQuantity(basStock1.getQuantity()); + item.setLevelRelation(basStock1.getSpare1()); + item.setUpperMaterial(basStock1.getSpare2()); + item.setTopMaterial(basStock1.getSpare3()); + item.setLotNo(basStock1.getLotNo()); + item.setAreaBefore(moveMsg.getOldSpace()); + //item.setLocationBefore(moveMsg.getTrayCode()); + item.setArea(moveMsg.getNewSpace()); + item.setLocation(moveMsg.getTrayCode()); + deliveryNoticeItemVos.add(item); + } + deliveryNoticeVo.setDetailList(deliveryNoticeItemVos); + + + //code success msg + RequestLog requestLog = requestLogService.getRequestLog("http://192.168.188.235/app1/api?type=1&key=2", JSONUtil.toJsonStr(deliveryNoticeVo), "移库回传", "wms", "erp"); + moveMsg.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + if ("1".equals(requestLog.getIsSuccessful())) { + moveMsg.setStatus("1"); + moveMsg.setMsg("成功"); + } else { + moveMsg.setStatus("2"); + moveMsg.setMsg(requestLog.getErrorDetails()); + } + + moveMsgService.updateMoveMsg(moveMsg); + } + } catch (Exception e) { + moveMsg.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + moveMsg.setStatus("2"); + moveMsg.setMsg(e.getMessage()); + moveMsgService.updateMoveMsg(moveMsg); + } } + @Override public AjaxResult createWorkshopInboundOrder(BasProduct basProduct) { ErpInterfaceParam param = new ErpInterfaceParam<>(); @@ -382,19 +963,249 @@ public class ToErpServiceImpl implements IToErpService { objectErpParameter.setDatas(List.of(wipTransferDoc)); erpStdData.setParameter(objectErpParameter); param.setStd_data(erpStdData); - RequestLog requestLog = requestLogService.getRequestLog(WORKSHOP_INBOUND_ORDER_URL, JSONUtil.toJsonStr(param), "创建工艺单","wms","erp"); + RequestLog requestLog = requestLogService.getRequestLog(WORKSHOP_INBOUND_ORDER_URL, JSONUtil.toJsonStr(param), "创建工艺单", "wms", "erp"); // String post = requestLog.getResponseBody(); // ErpInterfaceParam bean = JSONUtil.toBean(post, ErpInterfaceParam.class); // if ("0".equals(bean.getStd_data().getExecution().getCode())) { // return AjaxResult.success(); // } - if(requestLog != null && "1".equals(requestLog.getIsSuccessful())){ + if (requestLog != null && "1".equals(requestLog.getIsSuccessful())) { return AjaxResult.success(); - }else{ + } else { return AjaxResult.error(); } } + @Override + public void callbackInDeliveryNoticeNew() { + + InStockinBack inStockin = inStockinBackService.selectTopInStockin(); + if (inStockin == null) { + return; + } + CallBackErp callBackErp = new CallBackErp(); + callBackErp.setCcompany(inStockin.getCompanyShortName()); // 公司简称 + callBackErp.setCcode(inStockin.getStockinId()); // wms 单据号 需要改成作业号 + callBackErp.setDdate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); // 操作日期 + callBackErp.setCintype(inStockin.getInType()); // 业务类型 + callBackErp.setCvencode(inStockin.getSupplierNo()); // 供应商编码 + callBackErp.setCvenname(inStockin.getClassNo()); // 供应商名称 + callBackErp.setCoptname(inStockin.getCreateManId()); // 操作人 + callBackErp.setCmemo(inStockin.getRemark()); // 备注 + callBackErp.setCacc_id(inStockin.getAccountSetNo()); // 账套号 + callBackErp.setCwhcode("01"); // 仓库编码 + callBackErp.setCwhname("立体库"); // 仓库名称 + + + // TODO 以下需要重新编写根据给的字段 + InStockinDetailBack inStockinDetailParam = new InStockinDetailBack(); + inStockinDetailParam.setStockinId(inStockin.getStockinId()); + inStockinDetailParam.setSendStatus("0"); + List inStockinDetails = inStockinDetailBackService.selectInStockinDetailBackList(inStockinDetailParam); + + List detailList = new ArrayList<>(); + if (inStockinDetails != null && !inStockinDetails.isEmpty()) { + for (InStockinDetailBack detail : inStockinDetails) { + CallBackErpItems item = new CallBackErpItems(); + // 存货编码11 + item.setCinvcode(detail.getProductId()); + // 存货名称 + item.setCinvname(detail.getProductName()); + // 规格型号 + item.setCinvstd(detail.getSpec()); + // 单位 + item.setCinvm_unit(detail.getUnit()); + // 货位编码 + item.setCposcode(detail.getSpare9()); + item.setJobid(detail.getStockinGuid()); + // 货位名称 + item.setCposname(""); + // 托盘号 + item.setCtrayname(detail.getSpare8()); + //jobid +// item.setJobid(detail.getSpare7()); + // 批号 + item.setCbatch(detail.getLotNo()); + // 数量 + item.setIquantity(Integer.valueOf(detail.getAssignNum())); + // 老项目号 + item.setCxmh(detail.getOldProjectNo()); + // 新项目号 + item.setCnewxmh(detail.getSpare4()); + // erpbillno + item.setSrccode(inStockin.getErpBill()); + // erp来源单子表id + item.setSrcids(Integer.valueOf(detail.getSourceLineId())); + // erp子表行号 + item.setSrcrowno(detail.getSpare6()); + // 是否批次管理 + item.setBinvbatch(Integer.valueOf(detail.getIsBatchManage())); + // 仓库选择 1立库 2 平库 + item.setStg_location(detail.getProductGuid()); + // 组件号 + + System.err.println("组件号赋值 " + detail.getCargoNo()); + item.setGroupNum(detail.getCargoNo()); + System.err.println("组件号赋值 结束"); + detailList.add(item); + } + } + callBackErp.setDetails(detailList); + + String sendMsg = JSONUtil.toJsonStr(callBackErp); + System.err.println(sendMsg); + try { + //todo 发送给erp 成功失败改状态 + // http://192.168.188.235/app1/api?type=1&key=1 + RequestLog requestLog = requestLogService.getRequestLog("https://192.168.188.239:1093/hzgmid/ServerCommand/SaveDataFromWms", JSONUtil.toJsonStr(callBackErp), "入库回传", "wms", "erp", inStockin.getInType(), inStockin.getAccountSetNo()); + if ("1".equals(requestLog.getIsSuccessful())) { + inStockin.setSendStatus("1"); + inStockin.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + inStockin.setMsg("成功"); + inStockinDetailParam.setSendStatus("1"); + inStockinDetailParam.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + inStockinDetailParam.setMsg("成功"); + inStockinDetailBackService.insertInStockInDetailBackFinish(inStockinDetails); + inStockinDetailBackService.deleteInStockInDetailList(inStockinDetails); + } else { + inStockin.setSendStatus("2"); + inStockin.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + inStockin.setMsg(requestLog.getErrorDetails()); + inStockinDetailParam.setSendStatus("2"); + inStockinDetailParam.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + inStockinDetailParam.setMsg(requestLog.getErrorDetails()); + } + inStockinBackService.updateInStockinBack(inStockin); + inStockinDetailBackService.updateInStockinDetailBack(inStockinDetailParam); + + } catch (Exception e) { + inStockin.setSendStatus("2"); + inStockin.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + inStockin.setMsg(e.getMessage()); + inStockinDetailParam.setSendStatus("2"); + inStockinDetailParam.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + inStockinDetailParam.setMsg(e.getMessage()); + inStockinBackService.updateInStockinBack(inStockin); + inStockinDetailBackService.updateInStockinDetailBack(inStockinDetailParam); + } + + } + + @Override + public void callbackDeliveryOutNoticeNew() { + OutStockoutBack outStockoutBack = outStockoutBackService.selelctTopOutStockout(); + if (outStockoutBack == null) { + return; + } + CallBackErp callBackErp = new CallBackErp(); + callBackErp.setCcompany(outStockoutBack.getCompanyShortName()); // 公司简称 + callBackErp.setCcode(outStockoutBack.getStockoutId()); // wms 单据号 + callBackErp.setDdate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); // 操作日期 + callBackErp.setCintype(outStockoutBack.getOutType()); // 业务类型 + callBackErp.setCvencode(outStockoutBack.getCustomerNo()); // 供应商编码 + callBackErp.setCvenname(outStockoutBack.getCustomerNo()); // 供应商名称 + callBackErp.setCoptname(outStockoutBack.getCreateManId()); // 操作人 + callBackErp.setCmemo(outStockoutBack.getRemark()); // 备注 + callBackErp.setCacc_id(outStockoutBack.getAccountSetNo()); // 账套号 + callBackErp.setCwhcode("01"); // 仓库编码 + callBackErp.setCwhname("立体库"); // 仓库名称 + + + OutStockoutDetailBack outStockoutDetailBack = new OutStockoutDetailBack(); + outStockoutDetailBack.setStockoutId(outStockoutBack.getStockoutId()); + outStockoutDetailBack.setSendStatus("0"); +// outStockoutDetailBack.setSendStatus("0"); + List outStockoutDetailBacks = outStockoutDetailBackService.selectOutStockoutDetailBackList(outStockoutDetailBack); + List detailList = new ArrayList<>(); + if (outStockoutDetailBacks != null && !outStockoutDetailBacks.isEmpty()) { + for (OutStockoutDetailBack detail : outStockoutDetailBacks) { + CallBackErpItems item = new CallBackErpItems(); + // 存货编码 + item.setCinvcode(detail.getProductId()); + // 存货名称 + item.setCinvname(detail.getProductName()); + // 规格型号 + item.setCinvstd(detail.getSpec()); + // 单位 + item.setCinvm_unit(detail.getUnit()); + // 货位编码 + item.setCposcode(detail.getSpare9()); + // 货位名称 + item.setCposname(""); + // 托盘号 + item.setCtrayname(detail.getSpare8()); + // 批号 + item.setCbatch(detail.getLotNo()); + + item.setJobid(detail.getStockoutGuid()); +// item.setLotNo(detail.getLotNo()); + // 数量 + item.setIquantity(Integer.parseInt(String.valueOf(detail.getAssignNum()))); + // 老项目号 + item.setCxmh(detail.getOldProjectNo()); + // 新项目号 + item.setCnewxmh(detail.getSpare4()); + // erpbillno + item.setSrccode(outStockoutBack.getErpStockoutId()); + // erp来源单子表id + item.setSrcids(Integer.valueOf(detail.getSourceLineId())); + // erp子表行号 + item.setSrcrowno(detail.getSpare6()); + // 是否批次管理 + item.setBinvbatch(Integer.valueOf(detail.getIsBatchManage())); + // 仓库选择 1立库 2 平库 + item.setStg_location(detail.getProductGuid()); + // TODO 暂时未启用 等甲方后续通知 + item.setGroupNum(detail.getEntryid()); + + detailList.add(item); + } + callBackErp.setDetails(detailList); + + } + + try { + //todo 发送给erp 成功失败改状态 + RequestLog requestLog = requestLogService.getRequestLog("https://192.168.188.239:1093/hzgmid/ServerCommand/SaveDataFromWms", JSONUtil.toJsonStr(callBackErp), "出库回传", "wms", "erp", outStockoutBack.getOutType(), outStockoutBack.getAccountSetNo()); + if ("1".equals(requestLog.getIsSuccessful())) { + outStockoutBack.setSendStatus("1"); + outStockoutBack.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + outStockoutBack.setMsg("成功"); + outStockoutDetailBack.setSendStatus("1"); + outStockoutDetailBack.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + outStockoutDetailBack.setMsg("成功"); + outStockoutDetailBackService.insertOutStockDetailBackFinish(outStockoutDetailBacks); + outStockoutDetailBackService.deleteOutStockDetailList(outStockoutDetailBacks); + + } else { + outStockoutBack.setSendStatus("2"); + outStockoutBack.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + outStockoutBack.setMsg(requestLog.getErrorDetails()); + outStockoutDetailBack.setSendStatus("2"); + outStockoutDetailBack.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + outStockoutDetailBack.setMsg(requestLog.getErrorDetails()); + } + outStockoutBackService.updateOutStockoutBack(outStockoutBack); + outStockoutDetailBackService.updateOutStockoutDetailBack(outStockoutDetailBack); + + } catch (Exception e) { + outStockoutBack.setSendStatus("2"); + outStockoutBack.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + outStockoutBack.setMsg(e.getMessage()); + outStockoutDetailBack.setSendStatus("2"); + outStockoutDetailBack.setSendTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + outStockoutDetailBack.setMsg(e.getMessage()); + outStockoutBackService.updateOutStockoutBack(outStockoutBack); + outStockoutDetailBackService.updateOutStockoutDetailBack(outStockoutDetailBack); + } + + } + + @Override + public void callbackDeliveryOutNoticeNews() { + + } + public AjaxResult createOtherInOutboundOrder(TransferBillCallback transferBillCallback) { ErpInterfaceParam param = new ErpInterfaceParam<>(); @@ -404,10 +1215,10 @@ public class ToErpServiceImpl implements IToErpService { ErpInOutBoundOrder erpInOutBoundOrder = new ErpInOutBoundOrder(); String docNo = ""; String docIdDocCode = ""; - if ("1".equals(transferBillCallback.getType())){ + if ("1".equals(transferBillCallback.getType())) { docNo = basJobIdService.getJobId("11T1"); docIdDocCode = "11T1"; - }else { + } else { docNo = basJobIdService.getJobId("11T2"); docIdDocCode = "11T2"; } @@ -428,7 +1239,7 @@ public class ToErpServiceImpl implements IToErpService { for (int i = 0; i < mydoJobDetails.size(); i++) { MydoJobDetail mydoJobDetail = mydoJobDetails.get(i); ErpTransactionDocD erpTransactionDocD = new ErpTransactionDocD(); - erpTransactionDocD.setSequenceNumber(i+1); + erpTransactionDocD.setSequenceNumber(i + 1); erpTransactionDocD.setITEM_ID_ITEM_CODE(mydoJobDetail.getProductId()); erpTransactionDocD.setITEM_DESCRIPTION(mydoJobDetail.getProductName()); erpTransactionDocD.setITEM_SPECIFICATION(mydoJobDetail.getSpec()); @@ -444,11 +1255,11 @@ public class ToErpServiceImpl implements IToErpService { objectErpParameter.setDatas(list); erpStdData.setParameter(objectErpParameter); param.setStd_data(erpStdData); - RequestLog requestLog = requestLogService.getRequestLog( OTHER_IN_OUTBOUND_ORDER_URL, JSONUtil.toJsonStr(param), "创建其他入出库单","wms","erp"); + RequestLog requestLog = requestLogService.getRequestLog(OTHER_IN_OUTBOUND_ORDER_URL, JSONUtil.toJsonStr(param), "创建其他入出库单", "wms", "erp"); - if(requestLog != null && "1".equals(requestLog.getIsSuccessful())){ + if (requestLog != null && "1".equals(requestLog.getIsSuccessful())) { return AjaxResult.success(); - }else{ + } else { return AjaxResult.error(); } // String post = requestLog.getResponseBody(); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWcsServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWcsServiceImpl.java index 967dda8..0c5e949 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWcsServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWcsServiceImpl.java @@ -33,7 +33,7 @@ public class ToWcsServiceImpl implements IToWcsService { @Autowired private IAgvContainerTaskService agvContainerTaskService; - public static final String PUSH_OUT_MYDO_JOB = "http://localhost:8081/wcs2Wms/api/receiveOutMydoJob"; + public static final String PUSH_OUT_MYDO_JOB = "http://192.168.188.236:8081/wcs2Wms/api/receiveOutMydoJob"; public static final String PUSH_IN_MYDO_JOB = "http://localhost:8081/wcs2Wms/api/receiveInMydoJob"; public static final String PUSH_AGV_MOVE_JOB = "http://localhost:8081/agv/api/receiveAgvMoveJob"; public static final String OUT_MYDOJOB_MS = "http://localhost:8081/wcs2Wms/api/outMydojobMakesure"; @@ -43,15 +43,12 @@ public class ToWcsServiceImpl implements IToWcsService { @Override -// @Scheduled(fixedDelay=1500) + @Scheduled(fixedDelay=1500) public void pushOutMydoJob() { //查询所有未推送的料箱出库作业 MydoJob mydoJobParam = new MydoJob(); mydoJobParam.setStatus("1"); - List list = new ArrayList<>(); - list.add("21"); - list.add("26"); - mydoJobParam.setInOutIds(list); + mydoJobParam.setInOut("2"); List outMydoJobs = mydoJobService.selectMydoJobListApi(mydoJobParam); for (MydoJob outMydoJob : outMydoJobs) { RequestLog requestLog = requestLogService.getRequestLog(PUSH_OUT_MYDO_JOB, JSONUtil.toJsonStr(outMydoJob), "推送出库任务","wms","wcs"); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java index faa09e5..769425a 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ToWmsServiceImpl.java @@ -6,6 +6,10 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; +import com.ruoyi.algorithm.wms.InboundAllocationResult; +import com.ruoyi.algorithm.wms.OutboundWorkflowCoordinator; +import com.ruoyi.algorithm.wms.WmsInboundAllocationService; +import com.ruoyi.algorithm.wms.tidy.TidyWorkflowTransaction; import com.ruoyi.api.domain.*; import com.ruoyi.api.service.IToErpService; import com.ruoyi.api.service.IToWmsService; @@ -34,6 +38,7 @@ import com.ruoyi.job.mydojob.mapper.MydoJobMapper; import com.ruoyi.job.mydojob.service.IMydoJobService; import com.ruoyi.job.mydojobdetail.domain.MydoJobDetail; import com.ruoyi.job.mydojobdetail.service.IMydoJobDetailService; +import com.ruoyi.job.mydojobfinish.service.IMydoJobFinishService; import com.ruoyi.log.service.IRequestLogService; import com.ruoyi.out.outStockout.service.IOutStockoutService; import com.ruoyi.stock.stock.domain.BasStock; @@ -57,6 +62,8 @@ public class ToWmsServiceImpl implements IToWmsService { @Autowired private IMydoJobService mydoJobService; @Autowired + private IMydoJobFinishService mydoJobFinishService; + @Autowired private IMydoJobDetailService mydoJobDetailService; @Autowired private IBasContainerService basContainerService; @@ -90,30 +97,38 @@ public class ToWmsServiceImpl implements IToWmsService { private IBasStockService stockService; @Autowired private MydoJobMapper mydoJobMapper; + @Autowired + private WmsInboundAllocationService inboundAllocationService; + @Autowired + private OutboundWorkflowCoordinator outboundWorkflowCoordinator; + @Autowired + private TidyWorkflowTransaction tidyWorkflowTransaction; @Override - @Transactional(rollbackFor = Exception.class) public AjaxResult requestEnterByTrayCode(RequestEnter requestEnter) { String trayCode = requestEnter.getTrayCode(); MydoJob inJob = mydoJobMapper.selectInJobByTrayCode(trayCode); if(inJob != null && Integer.parseInt(inJob.getInOrOut()) < 20){ - if(inJob.getCargoSpaceId() != null && !"".equals(inJob.getCargoSpaceId())){ - return AjaxResult.success(JSONUtil.toJsonStr(inJob)); - }else{ - //分配货位 - HashMap map = new HashMap<>(); +// if(inJob.getCargoSpaceId() != null && !"".equals(inJob.getCargoSpaceId())){ +// return AjaxResult.success(inJob); +// }else{ +// //分配货位 +// HashMap map = new HashMap<>(); +// +// map.put("v_tray_code", trayCode); +// mydoJobMapper.allotInJobSpace(map); +// if (!"10".equals(map.get("v_result").toString())) { +// return AjaxResult.error(map.get("v_resultmsg").toString()); +// }else{ +// +// } +// } + +// MydoJob inJob2 = mydoJobMapper.selectInJobByTrayCode(trayCode); + return AjaxResult.success(inJob); - map.put("v_tray_code", trayCode); - mydoJobMapper.allotInJobSpace(map); - if (!"10".equals(map.get("v_result").toString())) { - return AjaxResult.error(map.get("v_resultmsg").toString()); - }else{ - MydoJob inJob2 = mydoJobMapper.selectInJobByTrayCode(trayCode); - return AjaxResult.success(JSONUtil.toJsonStr(inJob2)); - } - } }else{ return AjaxResult.error("该条码无入库任务,请扫码绑定!"); } @@ -135,7 +150,7 @@ public class ToWmsServiceImpl implements IToWmsService { String productId = mydoJobDetail.getProductId(); BasProduct basProduct = basProductService.selectBasProductByProductId(productId); - int size = Convert.toInt(basProduct.getSpare10()); + int size = Convert.toInt(basProduct.getSpare10(), 0); //超大托盘不处理 直接返回 if (size == 5) { return new AjaxResult(3, "超大托盘"); @@ -164,6 +179,7 @@ public class ToWmsServiceImpl implements IToWmsService { } @Override + @Transactional(rollbackFor = Exception.class) public AjaxResult jobFinish(WmsJobRequest wmsJobRequest) { MydoJob mydoJobParam = new MydoJob(); switch (wmsJobRequest.getWmsType()) { @@ -180,10 +196,14 @@ public class ToWmsServiceImpl implements IToWmsService { mydoJobParam.setJobId(wmsJobRequest.getJobId()); List inMydoJobs = mydoJobService.selectMydoJobListApi(mydoJobParam); if (inMydoJobs.isEmpty()) { + if (mydoJobFinishService.selectMydoJobFinishByJobId(wmsJobRequest.getJobId()) != null) { + return AjaxResult.success(); + } return AjaxResult.error("任务不存在"); } MydoJob inMydoJob = inMydoJobs.get(0); mydoJobService.manualCompleted(inMydoJob, 1); + inboundAllocationService.completeInbound(inMydoJob); break; case "2": @@ -197,8 +217,28 @@ public class ToWmsServiceImpl implements IToWmsService { return AjaxResult.error("任务不存在"); } MydoJob outJob = outMydoJobs.get(0); + //出库作业 outJob.setExecutionPhase("2"); mydoJobService.updateMydoJob(outJob); + if (tidyWorkflowTransaction != null + && tidyWorkflowTransaction.onJobFinished(outJob.getJobId(), "OUTBOUND_FINISHED")) { + break; + } + outboundWorkflowCoordinator.onJobFinished(outJob.getJobId()); + break; + case "7": + //移库作业 + mydoJobParam.setTaskNo(wmsJobRequest.getTaskNo()); + List ykMydoJobs = mydoJobService.selectMydoJobListApi(mydoJobParam); + if (ykMydoJobs.isEmpty()) { + return AjaxResult.error("任务不存在"); + } + MydoJob ykJob = ykMydoJobs.get(0); + mydoJobService.ykCompleted(ykJob); + if (tidyWorkflowTransaction == null + || !tidyWorkflowTransaction.onJobFinished(ykJob.getJobId(), "MOVE_FINISHED")) { + outboundWorkflowCoordinator.onJobFinished(ykJob.getJobId()); + } break; default: @@ -210,22 +250,17 @@ public class ToWmsServiceImpl implements IToWmsService { @Override public AjaxResult reAssign(ReMaterialParam reMaterialParam) { - //重新分配货位 MydoJob mydoJob = mydoJobService.selectMydoJobByJobId(reMaterialParam.getJobId()); - String warehouseId = mydoJob.getWarehouseId(); - BasCargoSpace basCargoSpaceParam = new BasCargoSpace(); - basCargoSpaceParam.setWarehouseId(warehouseId); - basCargoSpaceParam.setRoadwayId(mydoJob.getRoadwayId()); - BasCargoSpace basCargoSpace = basCargoSpaceService.selectEmptyCargoSpaceByWarehouseId(basCargoSpaceParam); - if (basCargoSpace == null) { - log.error("没有空货位"); - return AjaxResult.error(MessageUtils.message("error.message20")); - } else { - mydoJob.setCargoSpaceId(basCargoSpace.getCargoSpaceId()); - mydoJob.setFaultFlag("1"); - mydoJobService.updateMydoJob(mydoJob); - return AjaxResult.success(new RequestEnterResponse(basCargoSpace.getCargoSpaceId(), null, mydoJob.getJobId())); + if (mydoJob == null) { + return AjaxResult.error("任务不存在"); } + InboundAllocationResult allocation = inboundAllocationService.reallocate(mydoJob, mydoJob.getEntranceId()); + if (!allocation.success()) { + return AjaxResult.error(allocation.message()).put("algorithmCode", allocation.code()); + } + MydoJob allocated = allocation.job(); + return AjaxResult.success(new RequestEnterResponse(allocated.getCargoSpaceId(), + allocated.getTrayCode(), allocated.getJobId())); } @Override @@ -385,5 +420,24 @@ public class ToWmsServiceImpl implements IToWmsService { return AjaxResult.error(erpProduct.getSys_MainId()+"物料不存在"); } + @Override + public AjaxResult requestEnterByTaskNo(RequestEnter requestEnter) { + String taskNo = requestEnter.getTaskNo(); + String deviceCode = requestEnter.getDeviceCode(); + MydoJob inJob = mydoJobMapper.selectInJobByTaskNo(taskNo); + if(inJob != null && Integer.parseInt(inJob.getInOrOut()) < 20){ + if(inJob.getCargoSpaceId() != null && !"".equals(inJob.getCargoSpaceId())){ + return AjaxResult.success(inJob); + } + InboundAllocationResult allocation = inboundAllocationService.allocate(inJob, deviceCode); + if (!allocation.success()) { + return AjaxResult.error(allocation.message()).put("algorithmCode", allocation.code()); + } + return AjaxResult.success(allocation.job()); + }else{ + return AjaxResult.error("该条码无入库任务,请扫码绑定!"); + } + } + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/TwinServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/TwinServiceImpl.java index 33bb28d..467a480 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/TwinServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/TwinServiceImpl.java @@ -5,6 +5,10 @@ import com.ruoyi.bas.cargoSpace.domain.BasCargoSpace; import com.ruoyi.bas.cargoSpace.service.IBasCargoSpaceService; import com.ruoyi.in.stockinfinish.domain.InStockinFinish; import com.ruoyi.in.stockinfinish.service.IInStockinFinishService; +import com.ruoyi.job.mydojob.domain.MydoJob; +import com.ruoyi.job.mydojob.service.IMydoJobService; +import com.ruoyi.job.mydojobdetail.domain.MydoJobDetail; +import com.ruoyi.job.mydojobdetail.service.IMydoJobDetailService; import com.ruoyi.out.outStockoutFinish.domain.OutStockoutFinish; import com.ruoyi.out.outStockoutFinish.service.IOutStockoutFinishService; import com.ruoyi.stock.stock.domain.BasStock; @@ -33,6 +37,10 @@ public class TwinServiceImpl implements ITwinService { private IInStockinFinishService inStockinFinishService; @Autowired private IOutStockoutFinishService outStockoutFinishService; + @Autowired + private IMydoJobService mydoJobService; + @Autowired + private IMydoJobDetailService mydoJobDetailService; @Override public Map getStockListOverview() { @@ -250,4 +258,62 @@ public class TwinServiceImpl implements ITwinService { result.put("monthOutStock", monthOutStock); return result; } + + @Override + public Map getCargo(String cargoSpaceName) { + BasStock basStock = new BasStock(); + basStock.setCargoSpaceId(cargoSpaceName); + List list = basStockService.selectBasStockList(basStock); + List> dataList = new ArrayList<>(); + for (BasStock stock : list) { + Map dataMap = new HashMap<>(); + dataMap.put("productId", stock.getProductId()); + dataMap.put("productName", stock.getProductName()); + dataMap.put("quantity", stock.getQuantity()); + dataMap.put("trayCode", stock.getTrayCode()); + dataList.add(dataMap); + } + Map result = new HashMap<>(); + result.put("data", dataList); + return result; + } + + @Override + public Map getTaskCargo(String taskNo) { + MydoJob mydoJob = new MydoJob(); + mydoJob.setTaskNo(taskNo); + List jobList = mydoJobService.selectMydoJobList(mydoJob); + List> dataList = new ArrayList<>(); + if (jobList != null && !jobList.isEmpty()) { + MydoJob job = jobList.get(0); + String jobId = job.getJobId(); + String inOrOutStr = job.getInOrOut(); + int inOrOut = 0; + try { + inOrOut = Integer.parseInt(inOrOutStr); + } catch (Exception e) { + // Ignore parse error + } + + List details = mydoJobDetailService.selectMydoJobDetailListByJobId(jobId); + for (MydoJobDetail detail : details) { + Map dataMap = new HashMap<>(); + dataMap.put("productId", detail.getProductId()); + dataMap.put("productName", detail.getProductName()); + + String quantity = "0"; + if (inOrOut < 20) { + quantity = detail.getInQuantity(); + } else { + quantity = detail.getOutQuantity(); + } + dataMap.put("quantity", quantity); + dataMap.put("trayCode", detail.getTrayCode()); + dataList.add(dataMap); + } + } + Map result = new HashMap<>(); + result.put("data", dataList); + return result; + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/controller/AgvPointController.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/controller/AgvPointController.java new file mode 100644 index 0000000..e447ad0 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/controller/AgvPointController.java @@ -0,0 +1,104 @@ +package com.ruoyi.bas.agvPoint.controller; + +import java.util.List; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.bas.agvPoint.domain.AgvPoint; +import com.ruoyi.bas.agvPoint.service.IAgvPointService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * agv站点Controller + * + * @author ruoyi + * @date 2026-03-17 + */ +@RestController +@RequestMapping("/bas/agvPoint") +public class AgvPointController extends BaseController +{ + @Autowired + private IAgvPointService agvPointService; + + /** + * 查询agv站点列表 + */ + @PreAuthorize("@ss.hasPermi('bas:agvPoint:list')") + @GetMapping("/list") + public TableDataInfo list(AgvPoint agvPoint) + { + startPage(); + List list = agvPointService.selectAgvPointList(agvPoint); + return getDataTable(list); + } + + /** + * 导出agv站点列表 + */ + @PreAuthorize("@ss.hasPermi('bas:agvPoint:export')") + @Log(title = "agv站点", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, AgvPoint agvPoint) + { + List list = agvPointService.selectAgvPointList(agvPoint); + ExcelUtil util = new ExcelUtil(AgvPoint.class); + util.exportExcel(response, list, "agv站点数据"); + } + + /** + * 获取agv站点详细信息 + */ + @PreAuthorize("@ss.hasPermi('bas:agvPoint:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) + { + return success(agvPointService.selectAgvPointById(id)); + } + + /** + * 新增agv站点 + */ + @PreAuthorize("@ss.hasPermi('bas:agvPoint:add')") + @Log(title = "agv站点", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody AgvPoint agvPoint) + { + return toAjax(agvPointService.insertAgvPoint(agvPoint)); + } + + /** + * 修改agv站点 + */ + @PreAuthorize("@ss.hasPermi('bas:agvPoint:edit')") + @Log(title = "agv站点", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody AgvPoint agvPoint) + { + return toAjax(agvPointService.updateAgvPoint(agvPoint)); + } + + /** + * 删除agv站点 + */ + @PreAuthorize("@ss.hasPermi('bas:agvPoint:remove')") + @Log(title = "agv站点", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable String[] ids) + { + return toAjax(agvPointService.deleteAgvPointByIds(ids)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/domain/AgvPoint.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/domain/AgvPoint.java new file mode 100644 index 0000000..c930af2 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/domain/AgvPoint.java @@ -0,0 +1,113 @@ +package com.ruoyi.bas.agvPoint.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; + +/** + * agv站点对象 agv_point + * + * @author ruoyi + * @date 2026-03-17 + */ +public class AgvPoint extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 序号 */ + private String id; + + /** 站点编号 */ + @Excel(name = "站点编号") + private String station; + + /** 类型 */ + @Excel(name = "类型") + private String type; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spare1; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spare2; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spare3; + + public void setId(String id) + { + this.id = id; + } + + public String getId() + { + return id; + } + + public void setStation(String station) + { + this.station = station; + } + + public String getStation() + { + return station; + } + + public void setType(String type) + { + this.type = type; + } + + public String getType() + { + return type; + } + + public void setSpare1(String spare1) + { + this.spare1 = spare1; + } + + public String getSpare1() + { + return spare1; + } + + public void setSpare2(String spare2) + { + this.spare2 = spare2; + } + + public String getSpare2() + { + return spare2; + } + + public void setSpare3(String spare3) + { + this.spare3 = spare3; + } + + public String getSpare3() + { + return spare3; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("station", getStation()) + .append("type", getType()) + .append("remark", getRemark()) + .append("spare1", getSpare1()) + .append("spare2", getSpare2()) + .append("spare3", getSpare3()) + .toString(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/domain/AgvTask.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/domain/AgvTask.java new file mode 100644 index 0000000..e6a75c6 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/domain/AgvTask.java @@ -0,0 +1,22 @@ +package com.ruoyi.bas.agvPoint.domain; + +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +@lombok.Data +@Getter +@Setter +public class AgvTask implements Serializable { + + private String startPoint; + private String endPoint; + private String type; + private String trayCode; + + + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/mapper/AgvPointMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/mapper/AgvPointMapper.java new file mode 100644 index 0000000..f673303 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/mapper/AgvPointMapper.java @@ -0,0 +1,61 @@ +package com.ruoyi.bas.agvPoint.mapper; + +import java.util.List; +import com.ruoyi.bas.agvPoint.domain.AgvPoint; + +/** + * agv站点Mapper接口 + * + * @author ruoyi + * @date 2026-03-17 + */ +public interface AgvPointMapper +{ + /** + * 查询agv站点 + * + * @param id agv站点主键 + * @return agv站点 + */ + public AgvPoint selectAgvPointById(String id); + + /** + * 查询agv站点列表 + * + * @param agvPoint agv站点 + * @return agv站点集合 + */ + public List selectAgvPointList(AgvPoint agvPoint); + + /** + * 新增agv站点 + * + * @param agvPoint agv站点 + * @return 结果 + */ + public int insertAgvPoint(AgvPoint agvPoint); + + /** + * 修改agv站点 + * + * @param agvPoint agv站点 + * @return 结果 + */ + public int updateAgvPoint(AgvPoint agvPoint); + + /** + * 删除agv站点 + * + * @param id agv站点主键 + * @return 结果 + */ + public int deleteAgvPointById(String id); + + /** + * 批量删除agv站点 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteAgvPointByIds(String[] ids); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/service/IAgvPointService.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/service/IAgvPointService.java new file mode 100644 index 0000000..f03a444 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/service/IAgvPointService.java @@ -0,0 +1,61 @@ +package com.ruoyi.bas.agvPoint.service; + +import java.util.List; +import com.ruoyi.bas.agvPoint.domain.AgvPoint; + +/** + * agv站点Service接口 + * + * @author ruoyi + * @date 2026-03-17 + */ +public interface IAgvPointService +{ + /** + * 查询agv站点 + * + * @param id agv站点主键 + * @return agv站点 + */ + public AgvPoint selectAgvPointById(String id); + + /** + * 查询agv站点列表 + * + * @param agvPoint agv站点 + * @return agv站点集合 + */ + public List selectAgvPointList(AgvPoint agvPoint); + + /** + * 新增agv站点 + * + * @param agvPoint agv站点 + * @return 结果 + */ + public int insertAgvPoint(AgvPoint agvPoint); + + /** + * 修改agv站点 + * + * @param agvPoint agv站点 + * @return 结果 + */ + public int updateAgvPoint(AgvPoint agvPoint); + + /** + * 批量删除agv站点 + * + * @param ids 需要删除的agv站点主键集合 + * @return 结果 + */ + public int deleteAgvPointByIds(String[] ids); + + /** + * 删除agv站点信息 + * + * @param id agv站点主键 + * @return 结果 + */ + public int deleteAgvPointById(String id); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/service/impl/AgvPointServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/service/impl/AgvPointServiceImpl.java new file mode 100644 index 0000000..f5176ff --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/agvPoint/service/impl/AgvPointServiceImpl.java @@ -0,0 +1,93 @@ +package com.ruoyi.bas.agvPoint.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.bas.agvPoint.mapper.AgvPointMapper; +import com.ruoyi.bas.agvPoint.domain.AgvPoint; +import com.ruoyi.bas.agvPoint.service.IAgvPointService; + +/** + * agv站点Service业务层处理 + * + * @author ruoyi + * @date 2026-03-17 + */ +@Service +public class AgvPointServiceImpl implements IAgvPointService +{ + @Autowired + private AgvPointMapper agvPointMapper; + + /** + * 查询agv站点 + * + * @param id agv站点主键 + * @return agv站点 + */ + @Override + public AgvPoint selectAgvPointById(String id) + { + return agvPointMapper.selectAgvPointById(id); + } + + /** + * 查询agv站点列表 + * + * @param agvPoint agv站点 + * @return agv站点 + */ + @Override + public List selectAgvPointList(AgvPoint agvPoint) + { + return agvPointMapper.selectAgvPointList(agvPoint); + } + + /** + * 新增agv站点 + * + * @param agvPoint agv站点 + * @return 结果 + */ + @Override + public int insertAgvPoint(AgvPoint agvPoint) + { + return agvPointMapper.insertAgvPoint(agvPoint); + } + + /** + * 修改agv站点 + * + * @param agvPoint agv站点 + * @return 结果 + */ + @Override + public int updateAgvPoint(AgvPoint agvPoint) + { + return agvPointMapper.updateAgvPoint(agvPoint); + } + + /** + * 批量删除agv站点 + * + * @param ids 需要删除的agv站点主键 + * @return 结果 + */ + @Override + public int deleteAgvPointByIds(String[] ids) + { + return agvPointMapper.deleteAgvPointByIds(ids); + } + + /** + * 删除agv站点信息 + * + * @param id agv站点主键 + * @return 结果 + */ + @Override + public int deleteAgvPointById(String id) + { + return agvPointMapper.deleteAgvPointById(id); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/controller/BasTraycodeController.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/controller/BasTraycodeController.java index 2860e5f..78f9860 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/controller/BasTraycodeController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/controller/BasTraycodeController.java @@ -71,6 +71,7 @@ public class BasTraycodeController extends BaseController @PostMapping public AjaxResult add(@RequestBody BasTraycode basTraycode) { + return toAjax(basTraycodeService.insertBasTraycode(basTraycode)); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/domain/BasTraycode.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/domain/BasTraycode.java index de122ce..7844fbd 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/domain/BasTraycode.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/domain/BasTraycode.java @@ -16,16 +16,16 @@ public class BasTraycode extends BaseEntity private static final long serialVersionUID = 1L; /** id */ - @Excel(name = "${bas.Traycode.id}") +// @Excel(name = "${bas.Traycode.id}") private Long id; /** 条码类型id */ - @Excel(name = "${bas.Traycode.formatId}") +// @Excel(name = "${bas.Traycode.formatId}") private Long formatId; private String formatName; /** 条码 */ - @Excel(name = "${bas.Traycode.trayCode}") + @Excel(name = "条码") private String trayCode; /** 备用字段1 */ @@ -33,7 +33,7 @@ public class BasTraycode extends BaseEntity private String spare1; /** 备用字段2 */ -// @Excel(name = "${bas.Traycode.spare2}") + @Excel(name = "是否可用",dictType = "sys_yes_no") private String spare2; /** 备用字段3 */ diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/mapper/BasTraycodeMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/mapper/BasTraycodeMapper.java index cb76145..68e80a6 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/mapper/BasTraycodeMapper.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/mapper/BasTraycodeMapper.java @@ -61,4 +61,6 @@ public interface BasTraycodeMapper public int deleteBasTraycodeByIds(Long[] ids); void insertBasTraycodeList(List list); + + Integer selectBasTrayCodeMax(); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/service/IBasTraycodeService.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/service/IBasTraycodeService.java index 28793c1..eeae6eb 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/service/IBasTraycodeService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/service/IBasTraycodeService.java @@ -61,4 +61,6 @@ public interface IBasTraycodeService public int deleteBasTraycodeById(Long id); void insertBasTraycodeList(List traycodeList); + + Integer selectBasTrayCodeMax(); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/service/impl/BasTraycodeServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/service/impl/BasTraycodeServiceImpl.java index f737b01..69ad881 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/service/impl/BasTraycodeServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/traycode/service/impl/BasTraycodeServiceImpl.java @@ -1,9 +1,12 @@ package com.ruoyi.bas.traycode.service.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.convert.Convert; import com.ruoyi.bas.traycode.domain.BasTraycode; import com.ruoyi.bas.traycode.mapper.BasTraycodeMapper; import com.ruoyi.bas.traycode.service.IBasTraycodeService; +import com.ruoyi.bas.traycodeformat.domain.BasTraycodeFormat; +import com.ruoyi.bas.traycodeformat.service.IBasTraycodeFormatService; import com.ruoyi.common.utils.DateUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -21,6 +24,8 @@ public class BasTraycodeServiceImpl implements IBasTraycodeService { @Autowired private BasTraycodeMapper basTraycodeMapper; + @Autowired + private IBasTraycodeFormatService basTraycodeFormatService; /** * 查询条码信息 @@ -55,8 +60,33 @@ public class BasTraycodeServiceImpl implements IBasTraycodeService @Override public int insertBasTraycode(BasTraycode basTraycode) { - basTraycode.setCreateTime(DateUtils.getNowDate()); - return basTraycodeMapper.insertBasTraycode(basTraycode); + try { + BasTraycodeFormat basTraycodeFormat = basTraycodeFormatService.selectBasTraycodeFormatById(basTraycode.getFormatId()); + + + int i1 = Integer.parseInt(basTraycode.getSpare1()); + //如果i<4位数,前面补0 + String code = ""; + for (int j = 0; j < i1; j++) { + code = String.format("%07d",Convert.toInt( basTraycodeFormat.getSerialRule()) + 1 + j); + if(basTraycodeFormat.getMaxNum() < Convert.toLong( code)){ + throw new RuntimeException("已生成最大值"); + } + String finalCode = basTraycodeFormat.getBarcodeFormat()+code; + basTraycode.setTrayCode(finalCode); + basTraycode.setSpare1(null); + basTraycode.setCreateTime(DateUtils.getNowDate()); + basTraycode.setSpare2("Y"); + basTraycodeMapper.insertBasTraycode(basTraycode); + + + } + basTraycodeFormat.setSerialRule(Convert.toLong( code).toString()); + basTraycodeFormatService.updateBasTraycodeFormat(basTraycodeFormat); + } catch (Exception e) { + throw new RuntimeException(e); + } + return 1; } /** @@ -103,4 +133,9 @@ public class BasTraycodeServiceImpl implements IBasTraycodeService basTraycodeMapper.insertBasTraycodeList(list); } } + + @Override + public Integer selectBasTrayCodeMax() { + return basTraycodeMapper.selectBasTrayCodeMax(); + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/bas/traycodeformat/service/impl/BasTraycodeFormatServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/bas/traycodeformat/service/impl/BasTraycodeFormatServiceImpl.java index f9d9031..7b4f3a0 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/bas/traycodeformat/service/impl/BasTraycodeFormatServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/bas/traycodeformat/service/impl/BasTraycodeFormatServiceImpl.java @@ -1,17 +1,13 @@ package com.ruoyi.bas.traycodeformat.service.impl; -import cn.hutool.core.util.StrUtil; -import com.ruoyi.bas.traycode.domain.BasTraycode; import com.ruoyi.bas.traycode.service.IBasTraycodeService; import com.ruoyi.bas.traycodeformat.domain.BasTraycodeFormat; import com.ruoyi.bas.traycodeformat.mapper.BasTraycodeFormatMapper; import com.ruoyi.bas.traycodeformat.service.IBasTraycodeFormatService; -import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.utils.DateUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.ArrayList; import java.util.List; /** @@ -79,20 +75,7 @@ public class BasTraycodeFormatServiceImpl implements IBasTraycodeFormatService public int updateBasTraycodeFormat(BasTraycodeFormat basTraycodeFormat) { BasTraycodeFormat old = selectBasTraycodeFormatById(basTraycodeFormat.getId()); - int oldSerialRule = Convert.toInt(old.getSerialRule()); - int newSerialRule = Convert.toInt(basTraycodeFormat.getSerialRule()); - - List traycodeList = new ArrayList<>(); - for (int i = oldSerialRule; i < newSerialRule; i++) { - BasTraycode basTraycode = new BasTraycode(); - basTraycode.setFormatId(basTraycodeFormat.getId()); - String traycode = old.getBarcodeFormat()+ StrUtil.padPre(Convert.toStr(i),5,'0'); - basTraycode.setTrayCode(traycode); - traycodeList.add(basTraycode); - } basTraycodeFormat.setUpdateTime(DateUtils.getNowDate()); - //插入条码信息 - basTraycodeService.insertBasTraycodeList(traycodeList); return basTraycodeFormatMapper.updateBasTraycodeFormat(basTraycodeFormat); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/check/stockcheck/service/impl/CheckStockinServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/check/stockcheck/service/impl/CheckStockinServiceImpl.java index e280463..7e08309 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/check/stockcheck/service/impl/CheckStockinServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/check/stockcheck/service/impl/CheckStockinServiceImpl.java @@ -182,8 +182,8 @@ public class CheckStockinServiceImpl implements ICheckStockinService { CheckStockinDetail checkStockinDetail = detailList.get(i); checkStockinDetail.setStockCheckDetailId(stockCheckId + "-" + (i + 1)); checkStockinDetail.setStockCheckId(stockCheckId); - BasProduct basProduct = productService.selectBasProductByProductId(checkStockinDetail.getProductId()); - checkStockinDetail.setProductGuid(basProduct.getProductGuid()); +// BasProduct basProduct = productService.selectBasProductByProductId(checkStockinDetail.getProductId()); +// checkStockinDetail.setProductGuid(basProduct.getProductGuid()); checkStockinDetail.setStockCheckGuid(checkStockin.getStockGuid()); checkStockinDetail.setScanNum("0"); checkStockinDetail.setAssignNum("0"); @@ -229,7 +229,7 @@ public class CheckStockinServiceImpl implements ICheckStockinService { checkStockinMapper.autoAllot(map); builder.append("行明细:" + checkStockinDetail.getStockCheckDetailId() + ",分配结果:" + map.get("v_resultmsg") + "
"); } - iToWcsService.pushOutMydoJob(); + //iToWcsService.pushOutMydoJob(); return AjaxResult.success(builder.toString()); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/device/agv/mapper/AgvContainerTaskMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/device/agv/mapper/AgvContainerTaskMapper.java index 7306baa..fdb6f30 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/device/agv/mapper/AgvContainerTaskMapper.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/device/agv/mapper/AgvContainerTaskMapper.java @@ -60,4 +60,6 @@ public interface AgvContainerTaskMapper public int deleteAgvContainerTaskByIds(Long[] ids); void insertHistory(Long id); + + void deleteAgvJobByOrder(String order); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/device/agv/service/IAgvContainerTaskService.java b/ruoyi-admin/src/main/java/com/ruoyi/device/agv/service/IAgvContainerTaskService.java index 7df0984..8dba646 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/device/agv/service/IAgvContainerTaskService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/device/agv/service/IAgvContainerTaskService.java @@ -60,4 +60,6 @@ public interface IAgvContainerTaskService public int deleteAgvContainerTaskById(Long id); void insertHistory(Long id); + + void deleteAgvJobByOrder(String order); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/device/agv/service/impl/AgvContainerTaskServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/device/agv/service/impl/AgvContainerTaskServiceImpl.java index b8307cb..075c419 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/device/agv/service/impl/AgvContainerTaskServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/device/agv/service/impl/AgvContainerTaskServiceImpl.java @@ -97,4 +97,9 @@ public class AgvContainerTaskServiceImpl implements IAgvContainerTaskService public void insertHistory(Long id) { agvContainerTaskMapper.insertHistory(id); } + + @Override + public void deleteAgvJobByOrder(String order) { + agvContainerTaskMapper.deleteAgvJobByOrder(order); + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/domain/InStockin.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/domain/InStockin.java index e82e973..802c4e2 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/domain/InStockin.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/domain/InStockin.java @@ -102,8 +102,54 @@ public class InStockin extends BaseEntity private String lotNo; private String materialDesc; + private String productId; private String startDate; + private String companyShortName; + private String accountSetNo; + private String cargoNo; + private String stockinDetailId; + + public String getProductId() { + return productId; + } + + public void setProductId(String productId) { + this.productId = productId; + } + + public String getStockinDetailId() { + return stockinDetailId; + } + + public void setStockinDetailId(String stockinDetailId) { + this.stockinDetailId = stockinDetailId; + } + + public String getCargoNo() { + return cargoNo; + } + + public void setCargoNo(String cargoNo) { + this.cargoNo = cargoNo; + } + + public String getCompanyShortName() { + return companyShortName; + } + + public void setCompanyShortName(String companyShortName) { + this.companyShortName = companyShortName; + } + + public String getAccountSetNo() { + return accountSetNo; + } + + public void setAccountSetNo(String accountSetNo) { + this.accountSetNo = accountSetNo; + } + private List typeData; public String getStartDate() { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/mapper/InStockinMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/mapper/InStockinMapper.java index 3be6e24..39f2f58 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/mapper/InStockinMapper.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/mapper/InStockinMapper.java @@ -66,4 +66,6 @@ public interface InStockinMapper void insertInStockinHistory(InStockin inStockin); List selectStockinByDetail(String stockinDetailId); + + List selectInStockinListBill(InStockin param); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/service/IInStockinService.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/service/IInStockinService.java index 6ceece1..a73599a 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/service/IInStockinService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/service/IInStockinService.java @@ -73,4 +73,6 @@ public interface IInStockinService public int deleteInStockinByStockinGuid(String stockinGuid); public List selectStockinByDetail(String stockinDetailId); + + List selectInStockinListBill(InStockin param); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/service/impl/InStockinServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/service/impl/InStockinServiceImpl.java index 0448f63..d9545af 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/service/impl/InStockinServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockin/service/impl/InStockinServiceImpl.java @@ -255,4 +255,9 @@ public class InStockinServiceImpl implements IInStockinService public List selectStockinByDetail(String stockinDetailId) { return inStockinMapper.selectStockinByDetail(stockinDetailId); } + + @Override + public List selectInStockinListBill(InStockin param) { + return inStockinMapper.selectInStockinListBill(param); + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockinback/domain/InStockinBack.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockinback/domain/InStockinBack.java index e97d854..e739fe0 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockinback/domain/InStockinBack.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockinback/domain/InStockinBack.java @@ -95,6 +95,24 @@ public class InStockinBack extends BaseEntity private String sendTime; private String msg; + private String companyShortName; + private String accountSetNo; + + public String getCompanyShortName() { + return companyShortName; + } + + public void setCompanyShortName(String companyShortName) { + this.companyShortName = companyShortName; + } + + public String getAccountSetNo() { + return accountSetNo; + } + + public void setAccountSetNo(String accountSetNo) { + this.accountSetNo = accountSetNo; + } public String getSendStatus() { return sendStatus; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/domain/InStockinDetailBack.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/domain/InStockinDetailBack.java index 68990fe..233d1f3 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/domain/InStockinDetailBack.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/domain/InStockinDetailBack.java @@ -152,6 +152,44 @@ public class InStockinDetailBack extends BaseEntity private String msg; + + private String sourceLineId; + private String barCode; + private String isBatchManage; + private String oldProjectNo; + + public String getSourceLineId() { + return sourceLineId; + } + + public void setSourceLineId(String sourceLineId) { + this.sourceLineId = sourceLineId; + } + + public String getBarCode() { + return barCode; + } + + public void setBarCode(String barCode) { + this.barCode = barCode; + } + + public String getIsBatchManage() { + return isBatchManage; + } + + public void setIsBatchManage(String isBatchManage) { + this.isBatchManage = isBatchManage; + } + + public String getOldProjectNo() { + return oldProjectNo; + } + + public void setOldProjectNo(String oldProjectNo) { + this.oldProjectNo = oldProjectNo; + } + public String getSendStatus() { return sendStatus; } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/mapper/InStockinDetailBackMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/mapper/InStockinDetailBackMapper.java index ede4f51..9ddc0ac 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/mapper/InStockinDetailBackMapper.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/mapper/InStockinDetailBackMapper.java @@ -4,6 +4,7 @@ import java.util.List; import com.ruoyi.in.stockin.domain.InStockin; import com.ruoyi.in.stockindeatilback.domain.InStockinDetailBack; +import org.apache.ibatis.annotations.Param; /** * 入库单据子信息Mapper接口 @@ -61,4 +62,8 @@ public interface InStockinDetailBackMapper * @return 结果 */ public int deleteInStockinDetailBackByStockinDetailIds(String[] stockinDetailIds); + + void insertInStockInDetailBackFinish(@Param("list") List inStockinDetailParam); + + void deleteInStockInDetailList(@Param("idList") List inStockinDetails); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/service/IInStockinDetailBackService.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/service/IInStockinDetailBackService.java index c511d79..9b1b1fb 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/service/IInStockinDetailBackService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/service/IInStockinDetailBackService.java @@ -58,4 +58,8 @@ public interface IInStockinDetailBackService * @return 结果 */ public int deleteInStockinDetailBackByStockinDetailId(String stockinDetailId); + + void insertInStockInDetailBackFinish(List inStockinDetails); + + void deleteInStockInDetailList(List inStockinDetails); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/service/impl/InStockinDetailBackServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/service/impl/InStockinDetailBackServiceImpl.java index 0821f61..9ec707c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/service/impl/InStockinDetailBackServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindeatilback/service/impl/InStockinDetailBackServiceImpl.java @@ -90,4 +90,14 @@ public class InStockinDetailBackServiceImpl implements IInStockinDetailBackServi { return inStockinDetailBackMapper.deleteInStockinDetailBackByStockinDetailId(stockinDetailId); } + + @Override + public void insertInStockInDetailBackFinish(List inStockinDetails) { + inStockinDetailBackMapper.insertInStockInDetailBackFinish(inStockinDetails); + } + + @Override + public void deleteInStockInDetailList(List inStockinDetails) { + inStockinDetailBackMapper.deleteInStockInDetailList(inStockinDetails); + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/domain/InStockinDetail.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/domain/InStockinDetail.java index 2f00a9d..c6080e8 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/domain/InStockinDetail.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/domain/InStockinDetail.java @@ -143,9 +143,13 @@ public class InStockinDetail extends BaseEntity private String status; private ExtraField extraField; + private String erpBill; private String warehouseName; private String warehouseId; - + private String sourceLineId; + private String barCode; + private String isBatchManage; + private String oldProjectNo; } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/mapper/InStockinDetailMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/mapper/InStockinDetailMapper.java index baa5ba4..93bbedd 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/mapper/InStockinDetailMapper.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/mapper/InStockinDetailMapper.java @@ -69,4 +69,6 @@ public interface InStockinDetailMapper void deleteInStockinDetailByStockinGuid(String stockinGuid); InStockinDetail selectStockinByDetailById(InStockinDetail inStockinDetail); + + List selectStockInByDetailByBarCode(String barCode); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/service/IInStockinDetailService.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/service/IInStockinDetailService.java index aef8ee6..075e964 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/service/IInStockinDetailService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/service/IInStockinDetailService.java @@ -81,4 +81,6 @@ public interface IInStockinDetailService public InStockinDetail selectStockinByDetailById(InStockinDetail inStockinDetail); + + List selectStockInByDetailByBarCode(String barCode); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/service/impl/InStockinDetailServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/service/impl/InStockinDetailServiceImpl.java index 1763b66..07d21a4 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/service/impl/InStockinDetailServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockindetail/service/impl/InStockinDetailServiceImpl.java @@ -127,4 +127,9 @@ public class InStockinDetailServiceImpl implements IInStockinDetailService return inStockinDetailMapper.selectStockinByDetailById(inStockinDetail); } + + @Override + public List selectStockInByDetailByBarCode(String barCode) { + return inStockinDetailMapper.selectStockInByDetailByBarCode(barCode); + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockinfinish/domain/InStockinFinish.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockinfinish/domain/InStockinFinish.java index 340a94c..ef1507d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockinfinish/domain/InStockinFinish.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockinfinish/domain/InStockinFinish.java @@ -89,6 +89,15 @@ public class InStockinFinish extends BaseEntity /** 备用字段5 */ @Excel(name = "备用字段5") private String spare5; + private String stockinDetailId; + + public String getStockinDetailId() { + return stockinDetailId; + } + + public void setStockinDetailId(String stockinDetailId) { + this.stockinDetailId = stockinDetailId; + } public void setStockinGuid(String stockinGuid) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/in/stockinfinish/service/impl/InStockinFinishServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/in/stockinfinish/service/impl/InStockinFinishServiceImpl.java index ad28711..7277d7f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/in/stockinfinish/service/impl/InStockinFinishServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/in/stockinfinish/service/impl/InStockinFinishServiceImpl.java @@ -102,7 +102,7 @@ public class InStockinFinishServiceImpl implements IInStockinFinishService } @Override - @DataScope(warehouseAlias = "is2") +// @DataScope(warehouseAlias = "is2") public List selectInStockinFinishListByInStockin(InStockin inStockin) { return inStockinFinishMapper.selectInStockinFinishListByInStockin(inStockin); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/domain/MydoJob.java b/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/domain/MydoJob.java index 8648241..8caa432 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/domain/MydoJob.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/domain/MydoJob.java @@ -124,6 +124,9 @@ public class MydoJob extends BaseEntity /** 重分标记 */ @Excel(name = "重分标记") private String faultFlag; + private String endPoint; + + private String inOut; @@ -133,6 +136,23 @@ public class MydoJob extends BaseEntity private String createRightTime; private String productId; + private String stockinDetailId; + + public String getEndPoint() { + return endPoint; + } + + public void setEndPoint(String endPoint) { + this.endPoint = endPoint; + } + + public String getStockinDetailId() { + return stockinDetailId; + } + + public void setStockinDetailId(String stockinDetailId) { + this.stockinDetailId = stockinDetailId; + } public String getProductId() { return productId; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/mapper/MydoJobMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/mapper/MydoJobMapper.java index d10a63f..793dd20 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/mapper/MydoJobMapper.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/mapper/MydoJobMapper.java @@ -82,5 +82,16 @@ public interface MydoJobMapper MydoJob selectInJobByTrayCode(@Param("trayCode") String trayCode); + MydoJob selectInJobByTaskNo(@Param("taskNo") String taskNo); + + void allotInJobSpace(HashMap map); + + void ykCompleted(HashMap map); + + void completeAlgorithmMove(HashMap map); + + void updateLed(HashMap map); + + void updateLedError(HashMap map); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/service/IMydoJobService.java b/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/service/IMydoJobService.java index 7bc45ff..0f60062 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/service/IMydoJobService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/service/IMydoJobService.java @@ -109,4 +109,6 @@ public interface IMydoJobService MydoJob selectMydoJobByEntranceId(MydoJob mydoJob); List getInJobBySerial(String serial); + + void ykCompleted(MydoJob outJob); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/service/impl/MydoJobServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/service/impl/MydoJobServiceImpl.java index f801eb1..eaead9b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/service/impl/MydoJobServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/job/mydojob/service/impl/MydoJobServiceImpl.java @@ -192,7 +192,7 @@ public class MydoJobServiceImpl implements IMydoJobService { List mydoJobDetails = mydoJobDetailService.selectMydoJobDetailList(param); for (MydoJobDetail mydoJobDetail : mydoJobDetails) { - String inOrOutDId = mydoJobDetail.getInOrOutDId(); + String inOrOutDId = mydoJobDetail.getStockinDetailId(); InStockinDetail inStockinDetail = inStockinDetailService.selectInStockinDetailByStockinDetailId(inOrOutDId); BigDecimal stockInNum = Convert.toBigDecimal(inStockinDetail.getScanNum()); BigDecimal jobInNum = Convert.toBigDecimal(mydoJobDetail.getInQuantity()); @@ -506,7 +506,7 @@ public class MydoJobServiceImpl implements IMydoJobService { msg = map.get("v_resultmsg").toString(); builder.append("托盘:" + basStock.getTrayCode() + ",分配结果:" + msg + "
"); } - iToWcsService.pushOutMydoJob(); + //iToWcsService.pushOutMydoJob(); if (!StrUtil.isEmpty(builder)) { return AjaxResult.warn(builder.toString()); } @@ -527,4 +527,25 @@ public class MydoJobServiceImpl implements IMydoJobService { public List getInJobBySerial(String trayCode) { return mydoJobMapper.getInJobBySerial(trayCode); } + + @Override + public void ykCompleted(MydoJob outJob) { + HashMap map = new HashMap<>(); + map.put("v_job_id", outJob.getJobId()); + map.put("v_result", null); + boolean algorithmMove = "28".equals(outJob.getInOrOut()); + if (algorithmMove) { + mydoJobMapper.completeAlgorithmMove(map); + } else { + mydoJobMapper.ykCompleted(map); + } + if (!"10".equals(String.valueOf(map.get("v_result")))) { + log.error("移库任务处理异常 异常代码{}", map.get("v_result")); + if (algorithmMove) { + throw new IllegalStateException("Algorithm move completion failed for job " + outJob.getJobId()); + } + }else{ + log.info("移库任务处理成功 jobId:[{}] trayCode:[{}]", outJob.getJobId(), outJob.getTrayCode()); + } + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/log/controller/RequestLogController.java b/ruoyi-admin/src/main/java/com/ruoyi/log/controller/RequestLogController.java index 226575a..339e569 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/log/controller/RequestLogController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/log/controller/RequestLogController.java @@ -85,6 +85,34 @@ public class RequestLogController extends BaseController return toAjax(requestLogService.updateRequestLog(requestLog)); } + + + + + @GetMapping("/getMethod") + public AjaxResult getMethod() + { + List strings=requestLogService.getMethod(); + return AjaxResult.success(requestLogService.getMethod()); + } + + // 获取原系统 + @GetMapping("/getSource") + public AjaxResult getSource() + { + List strings=requestLogService.getSource(); + return AjaxResult.success(requestLogService.getSource()); + } + // 获取目标系统 + @GetMapping("/getTarget") + public AjaxResult getTarget() + { + List strings=requestLogService.getTarget(); + return AjaxResult.success(requestLogService.getTarget()); + } + + + /** * 删除接口记录 */ diff --git a/ruoyi-admin/src/main/java/com/ruoyi/log/mapper/RequestLogMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/log/mapper/RequestLogMapper.java index ba0c60a..34d1da1 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/log/mapper/RequestLogMapper.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/log/mapper/RequestLogMapper.java @@ -59,4 +59,10 @@ public interface RequestLogMapper * @return 结果 */ public int deleteRequestLogByRequestIds(Long[] requestIds); + + List getMethod(); + + List getSource(); + + List getTarget(); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/log/service/IRequestLogService.java b/ruoyi-admin/src/main/java/com/ruoyi/log/service/IRequestLogService.java index bda1022..1a40a4c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/log/service/IRequestLogService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/log/service/IRequestLogService.java @@ -69,6 +69,7 @@ public interface IRequestLogService * @return */ public RequestLog getRequestLog(String url, String param, String remark,String source,String target); + public RequestLog getRequestLog(String url, String param, String remark,String source,String target,String billType,String ciccid); /** * 接收接口记录 * @@ -77,4 +78,12 @@ public interface IRequestLogService * @return */ public RequestLog getRequestLog(String param, String remark, AjaxResult ajaxResult); + + public RequestLog getRequestLogERP(String param, String remark, AjaxResult ajaxResult); + + List getMethod(); + + List getSource(); + + List getTarget(); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/log/service/impl/RequestLogServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/log/service/impl/RequestLogServiceImpl.java index f605af0..7c91349 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/log/service/impl/RequestLogServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/log/service/impl/RequestLogServiceImpl.java @@ -3,6 +3,8 @@ package com.ruoyi.log.service.impl; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.net.URLEncodeUtil; +import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; import com.ruoyi.common.core.domain.AjaxResult; @@ -122,8 +124,10 @@ public class RequestLogServiceImpl implements IRequestLogService requestLog.setRequestBody(param); requestLog.setRequestUrl(url); try { - String resStr = HttpUtil.post(url, param); +// String resStr = HttpRequest.post(url).contentType("application/x-www-from-urlencoded").timeout(2000).body(param).execute().body(); + String resStr = HttpUtil.post(url, param); + requestLog.setResponseBody(resStr); // 判断resStr的状态码,如果不是200抛出异常让catch捕获 if (!JSONUtil.isJsonObj(resStr)) { throw new RuntimeException("返回结果不是有效的JSON对象"); @@ -133,7 +137,6 @@ public class RequestLogServiceImpl implements IRequestLogService if (codeObj == null || !codeObj.toString().equals("200")) { throw new RuntimeException("请求失败,状态码: " + (codeObj != null ? codeObj.toString() : "null")); } - requestLog.setResponseBody(resStr); requestLog.setResponseTime(DateUtil.formatDateTime(new Date())); requestLog.setResponseStatus("1"); requestLog.setDuration(Convert.toStr(DateUtil.between(Convert.toDate(requestLog.getRequestTime()), Convert.toDate(requestLog.getResponseTime()), DateUnit.MS))); @@ -148,6 +151,53 @@ public class RequestLogServiceImpl implements IRequestLogService return requestLog; } + @Override + public RequestLog getRequestLog(String url, String param, String remark, String source, String target, String billType, String ciccid) { + String body = "datajson=" + param + + "&ibilltype=" + URLEncodeUtil.encodeAll(billType) + + "&cacc_id=" + URLEncodeUtil.encodeAll(ciccid); + + RequestLog requestLog = new RequestLog(); + requestLog.setRequestTime(DateUtil.formatDateTime(new Date())); + requestLog.setSourceSystem(source); + requestLog.setTargetSystem(target); + requestLog.setEndpoint(remark); + requestLog.setRequestMethod("post"); + requestLog.setRequestHeaders(null); + requestLog.setRequestBody(body); + requestLog.setRequestUrl(url); + try { + String resStr = HttpRequest.post(url) + .contentType("application/x-www-form-urlencoded;charset=UTF-8") + .body(body) + .execute().body(); + + requestLog.setResponseBody(resStr); + // 判断resStr的状态码,如果不是200抛出异常让catch捕获 + if (!JSONUtil.isJsonObj(resStr)) { + throw new RuntimeException("返回结果不是有效的JSON对象"); + } + cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(resStr); + Object codeObj = jsonObject.get("ErrCode"); + if (codeObj == null || !codeObj.toString().equals("0")) { + throw new RuntimeException("请求失败,状态码: " + (codeObj != null ? codeObj.toString() : "null")); + } + requestLog.setResponseTime(DateUtil.formatDateTime(new Date())); + requestLog.setResponseStatus("1"); + requestLog.setDuration(Convert.toStr(DateUtil.between(Convert.toDate(requestLog.getRequestTime()), Convert.toDate(requestLog.getResponseTime()), DateUnit.MS))); + requestLog.setIsSuccessful("1"); + } catch (Exception e) { + requestLog.setErrorDetails(e.getMessage()); + requestLog.setIsSuccessful("0"); + requestLog.setResponseStatus("0"); + } finally { + insertRequestLog(requestLog); + } + return requestLog; + } + + + /** * 插入请求日志 * @@ -173,4 +223,46 @@ public class RequestLogServiceImpl implements IRequestLogService requestLog.setResponseBody(Convert.toStr(ajaxResult.get("msg"))); return requestLog; } + + @Override + public RequestLog getRequestLogERP(String param, String remark, AjaxResult ajaxResult) { + RequestLog requestLog = new RequestLog(); + requestLog.setRequestTime(DateUtil.formatDateTime(new Date())); + requestLog.setRequestBody(param); + requestLog.setSourceSystem("erp"); + requestLog.setTargetSystem("wms"); + requestLog.setEndpoint(remark); + requestLog.setRequestMethod("post"); + requestLog.setResponseTime(DateUtil.formatDateTime(new Date())); + requestLog.setDuration(Convert.toStr(DateUtil.between(Convert.toDate(requestLog.getRequestTime()), Convert.toDate(requestLog.getResponseTime()), DateUnit.MS))); + requestLog.setResponseStatus("1"); + if (ajaxResult.isSuccess()){ + requestLog.setIsSuccessful("1"); + }else { + requestLog.setIsSuccessful("0"); + } + requestLog.setResponseBody(Convert.toStr(ajaxResult.get("msg"))); + return requestLog; + } + + @Override + public List getMethod() { + + return requestLogMapper.getMethod(); + } + + @Override + public List getSource() { + return requestLogMapper.getSource(); + } + + @Override + public List getTarget() { + return requestLogMapper.getTarget(); + } + + public static void main(String[] args) { + String aa = "{\"code\":\"200,\"success\":true,\"msg\":\"请求成功\"}"; + System.out.println(JSONUtil.isJsonObj(aa)); + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/handAllotStock/controller/ViewHandAllotStockController.java b/ruoyi-admin/src/main/java/com/ruoyi/out/handAllotStock/controller/ViewHandAllotStockController.java index 1378ddb..471961e 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/out/handAllotStock/controller/ViewHandAllotStockController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/handAllotStock/controller/ViewHandAllotStockController.java @@ -42,6 +42,9 @@ public class ViewHandAllotStockController extends BaseController public TableDataInfo list(ViewHandAllotStock viewHandAllotStock) { startPage(); + if (viewHandAllotStock.getWarehouseCode()==null||viewHandAllotStock.getWarehouseCode().equals("")){ + viewHandAllotStock.setWarehouseCode("1"); + } List list = viewHandAllotStockService.selectViewHandAllotStockList(viewHandAllotStock); return getDataTable(list); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/handAllotStock/domain/ViewHandAllotStock.java b/ruoyi-admin/src/main/java/com/ruoyi/out/handAllotStock/domain/ViewHandAllotStock.java index ede42a8..006e27f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/out/handAllotStock/domain/ViewHandAllotStock.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/handAllotStock/domain/ViewHandAllotStock.java @@ -4,6 +4,7 @@ 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; +import org.springframework.data.annotation.Transient; /** * 手动分配库存对象 view_hand_allot_stock @@ -187,7 +188,38 @@ public class ViewHandAllotStock extends BaseEntity @Excel(name = "货位锁") private String locked; - public void setStockId(String stockId) + @Transient + private String ktpType; + @Transient + private String productType; + @Transient + private String warehouseCode; + + public String getWarehouseCode() { + return warehouseCode; + } + + public void setWarehouseCode(String warehouseCode) { + this.warehouseCode = warehouseCode; + } + + public String getKtpType() { + return ktpType; + } + + public void setKtpType(String ktpType) { + this.ktpType = ktpType; + } + + public String getProductType() { + return productType; + } + + public void setProductType(String productType) { + this.productType = productType; + } + + public void setStockId(String stockId) { this.stockId = stockId; } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/controller/OutStockoutController.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/controller/OutStockoutController.java index e438e28..007188b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/controller/OutStockoutController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/controller/OutStockoutController.java @@ -35,7 +35,7 @@ public class OutStockoutController extends BaseController { /** * 查询出库主单列表 */ - @PreAuthorize("@ss.hasPermi('out:outStockout:list')") +// @PreAuthorize("@ss.hasPermi('out:outStockout:list')") @GetMapping("/list") public TableDataInfo list(OutStockout outStockout) { startPage(); @@ -51,7 +51,7 @@ public class OutStockoutController extends BaseController { /** * 导出出库主单列表 */ - @PreAuthorize("@ss.hasPermi('out:outStockout:export')") +// @PreAuthorize("@ss.hasPermi('out:outStockout:export')") @Log(title = "出库主单", businessType = BusinessType.EXPORT) @PostMapping("/export") public void export(HttpServletResponse response, OutStockout outStockout) { @@ -63,7 +63,7 @@ public class OutStockoutController extends BaseController { /** * 获取出库主单详细信息 */ - @PreAuthorize("@ss.hasPermi('out:outStockout:query')") +// @PreAuthorize("@ss.hasPermi('out:outStockout:query')") @GetMapping(value = "/{stockoutGuid}") public AjaxResult getInfo(@PathVariable("stockoutGuid") String stockoutGuid) { return success(outStockoutService.selectOutStockoutByStockoutGuid(stockoutGuid)); @@ -72,7 +72,7 @@ public class OutStockoutController extends BaseController { /** * 新增出库主单 */ - @PreAuthorize("@ss.hasPermi('out:outStockout:add')") +// @PreAuthorize("@ss.hasPermi('out:outStockout:add')") @Log(title = "出库主单", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@RequestBody OutStockout outStockout) { @@ -82,7 +82,7 @@ public class OutStockoutController extends BaseController { /** * 修改出库主单 */ - @PreAuthorize("@ss.hasPermi('out:outStockout:edit')") +// @PreAuthorize("@ss.hasPermi('out:outStockout:edit')") @Log(title = "出库主单", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@RequestBody OutStockout outStockout) { @@ -92,7 +92,7 @@ public class OutStockoutController extends BaseController { /** * 删除出库主单 */ - @PreAuthorize("@ss.hasPermi('out:outStockout:remove')") +// @PreAuthorize("@ss.hasPermi('out:outStockout:remove')") @Log(title = "出库主单", businessType = BusinessType.DELETE) @DeleteMapping("/{stockoutGuids}") public AjaxResult remove(@PathVariable String[] stockoutGuids) { @@ -107,7 +107,7 @@ public class OutStockoutController extends BaseController { */ @Log(title = "出库主单保存", businessType = BusinessType.OTHER) @PostMapping("/saveBill") - @PreAuthorize("@ss.hasPermi('out:outStockout:saveBill')") +// @PreAuthorize("@ss.hasPermi('out:outStockout:saveBill')") @ResponseBody public AjaxResult saveBill(@RequestBody OutStockoutVo outStockoutVo) { String stockOutId = outStockoutService.saveBill(outStockoutVo); @@ -117,7 +117,7 @@ public class OutStockoutController extends BaseController { /** * 出库单据状态改变 */ - @PreAuthorize("@ss.hasPermi('out:outStockout:changeStatus')") +// @PreAuthorize("@ss.hasPermi('out:outStockout:changeStatus')") @Log(title = "出库主单状态改变", businessType = BusinessType.OTHER) @RequestMapping("/changeStatus") @ResponseBody @@ -132,17 +132,24 @@ public class OutStockoutController extends BaseController { * @param stockoutId * @return */ - @PreAuthorize("@ss.hasPermi('out:outStockout:autoAllot')") +// @PreAuthorize("@ss.hasPermi('out:outStockout:autoAllot')") @Log(title = "出库单自动分配", businessType = BusinessType.OTHER) @GetMapping("/autoAllot") public AjaxResult autoAllot(@RequestParam("stockoutId") String stockoutId) { + // 修改出库方向 +// OutStockout outStockout = new OutStockout(); +// outStockout.setStockoutId(stockoutId); +// outStockout.setSpare8(spare8); +// outStockoutService.updateOutStockout(outStockout); + System.out.println(stockoutId); +// System.out.println(spare8); return outStockoutService.autoAllot(stockoutId); } /** * 手动分配 */ - @PreAuthorize("@ss.hasPermi('out:outStockout:manualAllot')") +// @PreAuthorize("@ss.hasPermi('out:outStockout:manualAllot')") @Log(title = "出库单手动分配", businessType = BusinessType.OTHER) @GetMapping("/manualAllot") public AjaxResult manualAllot(@RequestParam("stockList") String[] stockList, @RequestParam("stockoutDetailId") String stockoutDetailId) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/domain/OutStockout.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/domain/OutStockout.java index 8403648..ae75547 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/domain/OutStockout.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/domain/OutStockout.java @@ -91,6 +91,9 @@ public class OutStockout extends BaseEntity private String spare4; private String spare5; + private String spare6; + private String spare7; + private String spare8; private String customerName; @@ -99,9 +102,51 @@ public class OutStockout extends BaseEntity private String productId; private String productName; + private String companyShortName; + private String accountSetNo; + + public String getCompanyShortName() { + return companyShortName; + } + + public void setCompanyShortName(String companyShortName) { + this.companyShortName = companyShortName; + } + + public String getAccountSetNo() { + return accountSetNo; + } + + public void setAccountSetNo(String accountSetNo) { + this.accountSetNo = accountSetNo; + } private List typeData; + public String getSpare6() { + return spare6; + } + + public void setSpare6(String spare6) { + this.spare6 = spare6; + } + + public String getSpare7() { + return spare7; + } + + public void setSpare7(String spare7) { + this.spare7 = spare7; + } + + public String getSpare8() { + return spare8; + } + + public void setSpare8(String spare8) { + this.spare8 = spare8; + } + public List getTypeData() { return typeData; } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/mapper/OutStockoutMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/mapper/OutStockoutMapper.java index c5c4496..451f337 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/mapper/OutStockoutMapper.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/mapper/OutStockoutMapper.java @@ -68,4 +68,6 @@ public interface OutStockoutMapper OutStockout selectOutStockoutByStockoutId(String stockoutId); void manualAllot(HashMap map); + + void updateOutStockouts(OutStockout mainOut); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/IOutStockoutService.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/IOutStockoutService.java index 94b2787..0a97a3f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/IOutStockoutService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/IOutStockoutService.java @@ -73,4 +73,6 @@ public interface IOutStockoutService List selectOutStockoutListApi(OutStockout outStockoutParam); AjaxResult manualAllot(String[] stockList,String stockoutDetailId); + + void updateOutStockouts(OutStockout mainOut); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImpl.java index 02f0c1f..703f9be 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockout/service/impl/OutStockoutServiceImpl.java @@ -1,6 +1,9 @@ package com.ruoyi.out.outStockout.service.impl; import cn.hutool.core.util.StrUtil; +import com.ruoyi.algorithm.integration.SchedulingDecisionStatus; +import com.ruoyi.algorithm.wms.OutboundAllocationResult; +import com.ruoyi.algorithm.wms.WmsOutboundAllocationService; import com.ruoyi.api.service.IToWcsService; import com.ruoyi.bas.basJobId.service.IBasJobIdService; import com.ruoyi.common.annotation.DataScope; @@ -23,6 +26,7 @@ import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; +import java.util.ArrayList; import java.util.List; /** @@ -45,6 +49,8 @@ public class OutStockoutServiceImpl implements IOutStockoutService private IOutStockoutDetailService outStockoutDetailService; @Autowired private IToWcsService toWcsService; + @Autowired + private WmsOutboundAllocationService outboundAllocationService; /** * 查询出库主单 @@ -172,26 +178,25 @@ public class OutStockoutServiceImpl implements IOutStockoutService return AjaxResult.warn("单据未审核,请审核无误后再分配!"); } - HashMap map = new HashMap<>(); - StringBuilder stringBuilder = new StringBuilder(); + List messages = new ArrayList<>(); + List codes = new ArrayList<>(); OutStockoutDetail outStockoutDetail = new OutStockoutDetail(); outStockoutDetail.setStockoutId(stockoutId); List outStockoutDetails = outStockoutDetailService.selectOutStockoutDetailList(outStockoutDetail); for (OutStockoutDetail detail : outStockoutDetails) { if (detail.getAllotQuantity().compareTo(detail.getQuantity()) < 0){ - map.put("v_stockout_detail_id", detail.getStockoutDetailId()); - outStockoutMapper.autoAllot(map); - toWcsService.pushOutMydoJob(); - if (!"10".equals(map.get("v_result"))){ - stringBuilder.append(",").append(detail.getStockoutDetailId()+map.get("v_resultString")); + OutboundAllocationResult allocation = outboundAllocationService.allocateProject(outStockout, detail); + if (allocation.status() != SchedulingDecisionStatus.READY) { + codes.add(allocation.code()); + messages.add(detail.getStockoutDetailId() + ":" + allocation.message()); } }else{ - stringBuilder.append(",").append(detail.getStockoutDetailId()+"单据已分配完成"); - + codes.add("ALREADY_ALLOCATED"); + messages.add(detail.getStockoutDetailId() + "单据已分配完成"); } } - if (!StrUtil.isEmpty(stringBuilder.toString())){ - return AjaxResult.warn(stringBuilder.toString()); + if (!messages.isEmpty()){ + return AjaxResult.warn(String.join(",", messages)).put("algorithmCodes", codes); } return AjaxResult.success(); } @@ -203,20 +208,33 @@ public class OutStockoutServiceImpl implements IOutStockoutService @Override public AjaxResult manualAllot(String[] stockList, String stockoutDetailId) { - HashMap map = new HashMap<>(); - StringBuilder stringBuilder = new StringBuilder(); + OutStockoutDetail detail = outStockoutDetailMapper + .selectOutStockoutDetailByStockoutDetailId(stockoutDetailId); + if (detail == null) { + return AjaxResult.warn("出库明细不存在").put("algorithmCodes", List.of("DETAIL_NOT_FOUND")); + } + OutStockout stockout = outStockoutMapper.selectOutStockoutByStockoutId(detail.getStockoutId()); + if (stockout == null) { + return AjaxResult.warn("出库单不存在").put("algorithmCodes", List.of("DOCUMENT_NOT_FOUND")); + } + List messages = new ArrayList<>(); + List codes = new ArrayList<>(); for (String stock : stockList) { - map.put("v_stockout_detail_id", stockoutDetailId); - map.put("v_stock_id", stock); - outStockoutMapper.manualAllot(map); - toWcsService.pushOutMydoJob(); - if (!"10".equals(map.get("v_result"))){ - stringBuilder.append(",").append(stockoutDetailId+map.get("v_resultString")); + OutboundAllocationResult allocation = outboundAllocationService + .allocateExactStock(stockout, detail, stock); + if (allocation.status() != SchedulingDecisionStatus.READY) { + codes.add(allocation.code()); + messages.add(stock + ":" + allocation.message()); } } - if (!StrUtil.isEmpty(stringBuilder.toString())){ - return AjaxResult.warn(stringBuilder.toString()); + if (!messages.isEmpty()){ + return AjaxResult.warn(String.join(",", messages)).put("algorithmCodes", codes); } return AjaxResult.success(); } + + @Override + public void updateOutStockouts(OutStockout mainOut) { + outStockoutMapper.updateOutStockouts(mainOut); + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/controller/OutStockoutBackController.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/controller/OutStockoutBackController.java new file mode 100644 index 0000000..365d554 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/controller/OutStockoutBackController.java @@ -0,0 +1,104 @@ +package com.ruoyi.out.outStockoutBack.controller; + +import java.util.List; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.out.outStockoutBack.domain.OutStockoutBack; +import com.ruoyi.out.outStockoutBack.service.IOutStockoutBackService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 出库单据主信息Controller + * + * @author ruoyi + * @date 2026-02-02 + */ +@RestController +@RequestMapping("/out/outStockoutBack") +public class OutStockoutBackController extends BaseController +{ + @Autowired + private IOutStockoutBackService outStockoutBackService; + + /** + * 查询出库单据主信息列表 + */ + @PreAuthorize("@ss.hasPermi('out:outStockoutBack:list')") + @GetMapping("/list") + public TableDataInfo list(OutStockoutBack outStockoutBack) + { + startPage(); + List list = outStockoutBackService.selectOutStockoutBackList(outStockoutBack); + return getDataTable(list); + } + + /** + * 导出出库单据主信息列表 + */ + @PreAuthorize("@ss.hasPermi('out:outStockoutBack:export')") + @Log(title = "出库单据主信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, OutStockoutBack outStockoutBack) + { + List list = outStockoutBackService.selectOutStockoutBackList(outStockoutBack); + ExcelUtil util = new ExcelUtil(OutStockoutBack.class); + util.exportExcel(response, list, "出库单据主信息数据"); + } + + /** + * 获取出库单据主信息详细信息 + */ + @PreAuthorize("@ss.hasPermi('out:outStockoutBack:query')") + @GetMapping(value = "/{stockoutGuid}") + public AjaxResult getInfo(@PathVariable("stockoutGuid") String stockoutGuid) + { + return success(outStockoutBackService.selectOutStockoutBackByStockoutGuid(stockoutGuid)); + } + + /** + * 新增出库单据主信息 + */ + @PreAuthorize("@ss.hasPermi('out:outStockoutBack:add')") + @Log(title = "出库单据主信息", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody OutStockoutBack outStockoutBack) + { + return toAjax(outStockoutBackService.insertOutStockoutBack(outStockoutBack)); + } + + /** + * 修改出库单据主信息 + */ + @PreAuthorize("@ss.hasPermi('out:outStockoutBack:edit')") + @Log(title = "出库单据主信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody OutStockoutBack outStockoutBack) + { + return toAjax(outStockoutBackService.updateOutStockoutBack(outStockoutBack)); + } + + /** + * 删除出库单据主信息 + */ + @PreAuthorize("@ss.hasPermi('out:outStockoutBack:remove')") + @Log(title = "出库单据主信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{stockoutGuids}") + public AjaxResult remove(@PathVariable String[] stockoutGuids) + { + return toAjax(outStockoutBackService.deleteOutStockoutBackByStockoutGuids(stockoutGuids)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/domain/OutStockoutBack.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/domain/OutStockoutBack.java new file mode 100644 index 0000000..d8eca83 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/domain/OutStockoutBack.java @@ -0,0 +1,464 @@ +package com.ruoyi.out.outStockoutBack.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; + +/** + * 出库单据主信息对象 out_stockout_back + * + * @author ruoyi + * @date 2026-02-02 + */ +public class OutStockoutBack extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 546 guid */ + @Excel(name = "546 guid") + private String stockoutGuid; + + /** 546 单据编码 */ + @Excel(name = "546 单据编码") + private String stockoutId; + + /** 546 出库类型 */ + @Excel(name = "546 出库类型") + private String outType; + + /** 546 单据时间 */ + @Excel(name = "546 单据时间") + private String createDate; + + /** 项目号546 */ + @Excel(name = "项目号546") + private String departmentNo; + + /** 客户编码546 */ + @Excel(name = "客户编码546") + private String customerNo; + + /** 制单人546 */ + @Excel(name = "制单人546") + private String createManId; + + /** 546 单据状态 */ + @Excel(name = "546 单据状态") + private String status; + + /** 单据来源0自建单1接口 */ + @Excel(name = "单据来源0自建单1接口") + private String stockoutSource; + + /** 仓库ID546 */ + @Excel(name = "仓库ID546") + private String warehouseId; + + /** 客户名称546 */ + @Excel(name = "客户名称546") + private String classNowId; + + /** 出口 */ + @Excel(name = "出口") + private String exitId; + + /** 出库方式546 */ + @Excel(name = "出库方式546") + private String carNumber; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String FID; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String erpStockoutId; + + /** 546 */ + @Excel(name = "546") + private String startDate; + + /** 546 */ + @Excel(name = "546") + private String finishDate; + + /** 合同号546 */ + @Excel(name = "合同号546") + private String spare1; + + /** 销售订单号546 */ + @Excel(name = "销售订单号546") + private String spare2; + + /** 审核时间546 */ + @Excel(name = "审核时间546") + private String spare3; + + /** 审核人546 */ + @Excel(name = "审核人546") + private String spare4; + + /** 备注546 */ + @Excel(name = "备注546") + private String spare5; + + /** 配送方式546 1人工2agv */ + @Excel(name = "配送方式546 1人工2agv") + private String spare6; + + /** 出库配送终点546 */ + @Excel(name = "出库配送终点546") + private String spare7; + + /** 1缓存2线边546 */ + @Excel(name = "1缓存2线边546") + private String spare8; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String sendStatus; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String sendTime; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String msg; + + + + private String companyShortName; + private String accountSetNo; + + public String getCompanyShortName() { + return companyShortName; + } + + public void setCompanyShortName(String companyShortName) { + this.companyShortName = companyShortName; + } + + public String getAccountSetNo() { + return accountSetNo; + } + + public void setAccountSetNo(String accountSetNo) { + this.accountSetNo = accountSetNo; + } + + public void setStockoutGuid(String stockoutGuid) + { + this.stockoutGuid = stockoutGuid; + } + + public String getStockoutGuid() + { + return stockoutGuid; + } + + public void setStockoutId(String stockoutId) + { + this.stockoutId = stockoutId; + } + + public String getStockoutId() + { + return stockoutId; + } + + public void setOutType(String outType) + { + this.outType = outType; + } + + public String getOutType() + { + return outType; + } + + public void setCreateDate(String createDate) + { + this.createDate = createDate; + } + + public String getCreateDate() + { + return createDate; + } + + public void setDepartmentNo(String departmentNo) + { + this.departmentNo = departmentNo; + } + + public String getDepartmentNo() + { + return departmentNo; + } + + public void setCustomerNo(String customerNo) + { + this.customerNo = customerNo; + } + + public String getCustomerNo() + { + return customerNo; + } + + public void setCreateManId(String createManId) + { + this.createManId = createManId; + } + + public String getCreateManId() + { + return createManId; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + + public void setStockoutSource(String stockoutSource) + { + this.stockoutSource = stockoutSource; + } + + public String getStockoutSource() + { + return stockoutSource; + } + + public void setWarehouseId(String warehouseId) + { + this.warehouseId = warehouseId; + } + + public String getWarehouseId() + { + return warehouseId; + } + + public void setClassNowId(String classNowId) + { + this.classNowId = classNowId; + } + + public String getClassNowId() + { + return classNowId; + } + + public void setExitId(String exitId) + { + this.exitId = exitId; + } + + public String getExitId() + { + return exitId; + } + + public void setCarNumber(String carNumber) + { + this.carNumber = carNumber; + } + + public String getCarNumber() + { + return carNumber; + } + + public void setFID(String FID) + { + this.FID = FID; + } + + public String getFID() + { + return FID; + } + + public void setErpStockoutId(String erpStockoutId) + { + this.erpStockoutId = erpStockoutId; + } + + public String getErpStockoutId() + { + return erpStockoutId; + } + + public void setStartDate(String startDate) + { + this.startDate = startDate; + } + + public String getStartDate() + { + return startDate; + } + + public void setFinishDate(String finishDate) + { + this.finishDate = finishDate; + } + + public String getFinishDate() + { + return finishDate; + } + + public void setSpare1(String spare1) + { + this.spare1 = spare1; + } + + public String getSpare1() + { + return spare1; + } + + public void setSpare2(String spare2) + { + this.spare2 = spare2; + } + + public String getSpare2() + { + return spare2; + } + + public void setSpare3(String spare3) + { + this.spare3 = spare3; + } + + public String getSpare3() + { + return spare3; + } + + public void setSpare4(String spare4) + { + this.spare4 = spare4; + } + + public String getSpare4() + { + return spare4; + } + + public void setSpare5(String spare5) + { + this.spare5 = spare5; + } + + public String getSpare5() + { + return spare5; + } + + public void setSpare6(String spare6) + { + this.spare6 = spare6; + } + + public String getSpare6() + { + return spare6; + } + + public void setSpare7(String spare7) + { + this.spare7 = spare7; + } + + public String getSpare7() + { + return spare7; + } + + public void setSpare8(String spare8) + { + this.spare8 = spare8; + } + + public String getSpare8() + { + return spare8; + } + + public void setSendStatus(String sendStatus) + { + this.sendStatus = sendStatus; + } + + public String getSendStatus() + { + return sendStatus; + } + + public void setSendTime(String sendTime) + { + this.sendTime = sendTime; + } + + public String getSendTime() + { + return sendTime; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public String getMsg() + { + return msg; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("stockoutGuid", getStockoutGuid()) + .append("stockoutId", getStockoutId()) + .append("outType", getOutType()) + .append("createDate", getCreateDate()) + .append("departmentNo", getDepartmentNo()) + .append("customerNo", getCustomerNo()) + .append("createManId", getCreateManId()) + .append("status", getStatus()) + .append("stockoutSource", getStockoutSource()) + .append("warehouseId", getWarehouseId()) + .append("classNowId", getClassNowId()) + .append("exitId", getExitId()) + .append("carNumber", getCarNumber()) + .append("FID", getFID()) + .append("erpStockoutId", getErpStockoutId()) + .append("startDate", getStartDate()) + .append("finishDate", getFinishDate()) + .append("spare1", getSpare1()) + .append("spare2", getSpare2()) + .append("spare3", getSpare3()) + .append("spare4", getSpare4()) + .append("spare5", getSpare5()) + .append("spare6", getSpare6()) + .append("spare7", getSpare7()) + .append("spare8", getSpare8()) + .append("sendStatus", getSendStatus()) + .append("sendTime", getSendTime()) + .append("msg", getMsg()) + .toString(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/mapper/OutStockoutBackMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/mapper/OutStockoutBackMapper.java new file mode 100644 index 0000000..23e6665 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/mapper/OutStockoutBackMapper.java @@ -0,0 +1,64 @@ +package com.ruoyi.out.outStockoutBack.mapper; + +import java.util.List; +import com.ruoyi.out.outStockoutBack.domain.OutStockoutBack; + +/** + * 出库单据主信息Mapper接口 + * + * @author ruoyi + * @date 2026-02-02 + */ +public interface OutStockoutBackMapper +{ + /** + * 查询出库单据主信息 + * + * @param stockoutGuid 出库单据主信息主键 + * @return 出库单据主信息 + */ + public OutStockoutBack selectOutStockoutBackByStockoutGuid(String stockoutGuid); + + + public OutStockoutBack selelctTopOutStockout(); + + /** + * 查询出库单据主信息列表 + * + * @param outStockoutBack 出库单据主信息 + * @return 出库单据主信息集合 + */ + public List selectOutStockoutBackList(OutStockoutBack outStockoutBack); + + /** + * 新增出库单据主信息 + * + * @param outStockoutBack 出库单据主信息 + * @return 结果 + */ + public int insertOutStockoutBack(OutStockoutBack outStockoutBack); + + /** + * 修改出库单据主信息 + * + * @param outStockoutBack 出库单据主信息 + * @return 结果 + */ + public int updateOutStockoutBack(OutStockoutBack outStockoutBack); + + /** + * 删除出库单据主信息 + * + * @param stockoutGuid 出库单据主信息主键 + * @return 结果 + */ + public int deleteOutStockoutBackByStockoutGuid(String stockoutGuid); + + /** + * 批量删除出库单据主信息 + * + * @param stockoutGuids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteOutStockoutBackByStockoutGuids(String[] stockoutGuids); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/service/IOutStockoutBackService.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/service/IOutStockoutBackService.java new file mode 100644 index 0000000..b45d9f5 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/service/IOutStockoutBackService.java @@ -0,0 +1,70 @@ +package com.ruoyi.out.outStockoutBack.service; + +import java.util.List; +import com.ruoyi.out.outStockoutBack.domain.OutStockoutBack; + +/** + * 出库单据主信息Service接口 + * + * @author ruoyi + * @date 2026-02-02 + */ +public interface IOutStockoutBackService +{ + /** + * 查询出库单据主信息 + * + * @param stockoutGuid 出库单据主信息主键 + * @return 出库单据主信息 + */ + public OutStockoutBack selectOutStockoutBackByStockoutGuid(String stockoutGuid); + + + + + public OutStockoutBack selelctTopOutStockout(); + + + + /** + * 查询出库单据主信息列表 + * + * @param outStockoutBack 出库单据主信息 + * @return 出库单据主信息集合 + */ + public List selectOutStockoutBackList(OutStockoutBack outStockoutBack); + + /** + * 新增出库单据主信息 + * + * @param outStockoutBack 出库单据主信息 + * @return 结果 + */ + public int insertOutStockoutBack(OutStockoutBack outStockoutBack); + + /** + * 修改出库单据主信息 + * + * @param outStockoutBack 出库单据主信息 + * @return 结果 + */ + public int updateOutStockoutBack(OutStockoutBack outStockoutBack); + + /** + * 批量删除出库单据主信息 + * + * @param stockoutGuids 需要删除的出库单据主信息主键集合 + * @return 结果 + */ + public int deleteOutStockoutBackByStockoutGuids(String[] stockoutGuids); + + /** + * 删除出库单据主信息信息 + * + * @param stockoutGuid 出库单据主信息主键 + * @return 结果 + */ + public int deleteOutStockoutBackByStockoutGuid(String stockoutGuid); + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/service/impl/OutStockoutBackServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/service/impl/OutStockoutBackServiceImpl.java new file mode 100644 index 0000000..270369b --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutBack/service/impl/OutStockoutBackServiceImpl.java @@ -0,0 +1,98 @@ +package com.ruoyi.out.outStockoutBack.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.out.outStockoutBack.mapper.OutStockoutBackMapper; +import com.ruoyi.out.outStockoutBack.domain.OutStockoutBack; +import com.ruoyi.out.outStockoutBack.service.IOutStockoutBackService; + +/** + * 出库单据主信息Service业务层处理 + * + * @author ruoyi + * @date 2026-02-02 + */ +@Service +public class OutStockoutBackServiceImpl implements IOutStockoutBackService +{ + @Autowired + private OutStockoutBackMapper outStockoutBackMapper; + + /** + * 查询出库单据主信息 + * + * @param stockoutGuid 出库单据主信息主键 + * @return 出库单据主信息 + */ + @Override + public OutStockoutBack selectOutStockoutBackByStockoutGuid(String stockoutGuid) + { + return outStockoutBackMapper.selectOutStockoutBackByStockoutGuid(stockoutGuid); + } + + @Override + public OutStockoutBack selelctTopOutStockout() { + return outStockoutBackMapper.selelctTopOutStockout(); + } + + /** + * 查询出库单据主信息列表 + * + * @param outStockoutBack 出库单据主信息 + * @return 出库单据主信息 + */ + @Override + public List selectOutStockoutBackList(OutStockoutBack outStockoutBack) + { + return outStockoutBackMapper.selectOutStockoutBackList(outStockoutBack); + } + + /** + * 新增出库单据主信息 + * + * @param outStockoutBack 出库单据主信息 + * @return 结果 + */ + @Override + public int insertOutStockoutBack(OutStockoutBack outStockoutBack) + { + return outStockoutBackMapper.insertOutStockoutBack(outStockoutBack); + } + + /** + * 修改出库单据主信息 + * + * @param outStockoutBack 出库单据主信息 + * @return 结果 + */ + @Override + public int updateOutStockoutBack(OutStockoutBack outStockoutBack) + { + return outStockoutBackMapper.updateOutStockoutBack(outStockoutBack); + } + + /** + * 批量删除出库单据主信息 + * + * @param stockoutGuids 需要删除的出库单据主信息主键 + * @return 结果 + */ + @Override + public int deleteOutStockoutBackByStockoutGuids(String[] stockoutGuids) + { + return outStockoutBackMapper.deleteOutStockoutBackByStockoutGuids(stockoutGuids); + } + + /** + * 删除出库单据主信息信息 + * + * @param stockoutGuid 出库单据主信息主键 + * @return 结果 + */ + @Override + public int deleteOutStockoutBackByStockoutGuid(String stockoutGuid) + { + return outStockoutBackMapper.deleteOutStockoutBackByStockoutGuid(stockoutGuid); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetail/domain/OutStockoutDetail.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetail/domain/OutStockoutDetail.java index 4027dd2..a67c485 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetail/domain/OutStockoutDetail.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetail/domain/OutStockoutDetail.java @@ -48,7 +48,7 @@ public class OutStockoutDetail extends BaseEntity /** 计划数量(箱) */ @Excel(name = "计划数量", readConverterExp = "箱=") - private BigDecimal quantityX; + private String quantityX; /** 计划数量(件) */ @Excel(name = "计划数量", readConverterExp = "件=") @@ -200,6 +200,42 @@ public class OutStockoutDetail extends BaseEntity private String spare9; + private String sourceLineId; + private String barCode; + private String isBatchManage; + private String oldProjectNo; + + public String getSourceLineId() { + return sourceLineId; + } + + public void setSourceLineId(String sourceLineId) { + this.sourceLineId = sourceLineId; + } + + public String getBarCode() { + return barCode; + } + + public void setBarCode(String barCode) { + this.barCode = barCode; + } + + public String getIsBatchManage() { + return isBatchManage; + } + + public void setIsBatchManage(String isBatchManage) { + this.isBatchManage = isBatchManage; + } + + public String getOldProjectNo() { + return oldProjectNo; + } + + public void setOldProjectNo(String oldProjectNo) { + this.oldProjectNo = oldProjectNo; + } public String getSpare1() { return spare1; @@ -407,14 +443,12 @@ public class OutStockoutDetail extends BaseEntity return quantity; } - public void setQuantityX(BigDecimal quantityX) - { - this.quantityX = quantityX; + public String getQuantityX() { + return quantityX; } - public BigDecimal getQuantityX() - { - return quantityX; + public void setQuantityX(String quantityX) { + this.quantityX = quantityX; } public void setQuantityJ(BigDecimal quantityJ) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/controller/OutStockoutDetailBackController.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/controller/OutStockoutDetailBackController.java new file mode 100644 index 0000000..93b9bc9 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/controller/OutStockoutDetailBackController.java @@ -0,0 +1,104 @@ +package com.ruoyi.out.outStockoutDetailBack.controller; + +import java.util.List; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.out.outStockoutDetailBack.domain.OutStockoutDetailBack; +import com.ruoyi.out.outStockoutDetailBack.service.IOutStockoutDetailBackService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 历史出库单据子信息Controller + * + * @author ruoyi + * @date 2026-02-02 + */ +@RestController +@RequestMapping("/out/outStockoutDetailBack") +public class OutStockoutDetailBackController extends BaseController +{ + @Autowired + private IOutStockoutDetailBackService outStockoutDetailBackService; + + /** + * 查询历史出库单据子信息列表 + */ + @PreAuthorize("@ss.hasPermi('out:outStockoutDetailBack:list')") + @GetMapping("/list") + public TableDataInfo list(OutStockoutDetailBack outStockoutDetailBack) + { + startPage(); + List list = outStockoutDetailBackService.selectOutStockoutDetailBackList(outStockoutDetailBack); + return getDataTable(list); + } + + /** + * 导出历史出库单据子信息列表 + */ + @PreAuthorize("@ss.hasPermi('out:outStockoutDetailBack:export')") + @Log(title = "历史出库单据子信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, OutStockoutDetailBack outStockoutDetailBack) + { + List list = outStockoutDetailBackService.selectOutStockoutDetailBackList(outStockoutDetailBack); + ExcelUtil util = new ExcelUtil(OutStockoutDetailBack.class); + util.exportExcel(response, list, "历史出库单据子信息数据"); + } + + /** + * 获取历史出库单据子信息详细信息 + */ + @PreAuthorize("@ss.hasPermi('out:outStockoutDetailBack:query')") + @GetMapping(value = "/{stockoutDetailId}") + public AjaxResult getInfo(@PathVariable("stockoutDetailId") String stockoutDetailId) + { + return success(outStockoutDetailBackService.selectOutStockoutDetailBackByStockoutDetailId(stockoutDetailId)); + } + + /** + * 新增历史出库单据子信息 + */ + @PreAuthorize("@ss.hasPermi('out:outStockoutDetailBack:add')") + @Log(title = "历史出库单据子信息", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody OutStockoutDetailBack outStockoutDetailBack) + { + return toAjax(outStockoutDetailBackService.insertOutStockoutDetailBack(outStockoutDetailBack)); + } + + /** + * 修改历史出库单据子信息 + */ + @PreAuthorize("@ss.hasPermi('out:outStockoutDetailBack:edit')") + @Log(title = "历史出库单据子信息", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody OutStockoutDetailBack outStockoutDetailBack) + { + return toAjax(outStockoutDetailBackService.updateOutStockoutDetailBack(outStockoutDetailBack)); + } + + /** + * 删除历史出库单据子信息 + */ + @PreAuthorize("@ss.hasPermi('out:outStockoutDetailBack:remove')") + @Log(title = "历史出库单据子信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{stockoutDetailIds}") + public AjaxResult remove(@PathVariable String[] stockoutDetailIds) + { + return toAjax(outStockoutDetailBackService.deleteOutStockoutDetailBackByStockoutDetailIds(stockoutDetailIds)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/domain/OutStockoutDetailBack.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/domain/OutStockoutDetailBack.java new file mode 100644 index 0000000..9c6aea5 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/domain/OutStockoutDetailBack.java @@ -0,0 +1,645 @@ +package com.ruoyi.out.outStockoutDetailBack.domain; + +import java.math.BigDecimal; +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; + +/** + * 历史出库单据子信息对象 out_stockout_detail_back + * + * @author ruoyi + * @date 2026-02-02 + */ +public class OutStockoutDetailBack extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String stockoutDetailId; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String stockoutGuid; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String stockoutId; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String lotNo; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String productGuid; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String productId; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private BigDecimal quantity; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String quantityX; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private BigDecimal quantityJ; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private BigDecimal assignNum; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private BigDecimal assignNumX; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private BigDecimal assignNumJ; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private BigDecimal allotQuantity; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private BigDecimal allotQuantityX; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private BigDecimal allotQuantityJ; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String price; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String warehouseId; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String outId; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String bukechaiQuantity; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String kechaiQuantity; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String entryid; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String flatQuantity; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String fid; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String erpStockoutId; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String unit; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spec; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String productName; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spare1; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spare2; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spare3; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spare4; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spare5; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spare6; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spare7; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spare8; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String spare9; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String sendStatus; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String sendTime; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String msg; + + private String sourceLineId; + private String barCode; + private String isBatchManage; + private String oldProjectNo; + + public String getSourceLineId() { + return sourceLineId; + } + + public void setSourceLineId(String sourceLineId) { + this.sourceLineId = sourceLineId; + } + + public String getBarCode() { + return barCode; + } + + public void setBarCode(String barCode) { + this.barCode = barCode; + } + + public String getIsBatchManage() { + return isBatchManage; + } + + public void setIsBatchManage(String isBatchManage) { + this.isBatchManage = isBatchManage; + } + + public String getOldProjectNo() { + return oldProjectNo; + } + + public void setOldProjectNo(String oldProjectNo) { + this.oldProjectNo = oldProjectNo; + } + + public void setStockoutDetailId(String stockoutDetailId) + { + this.stockoutDetailId = stockoutDetailId; + } + + public String getStockoutDetailId() + { + return stockoutDetailId; + } + + public void setStockoutGuid(String stockoutGuid) + { + this.stockoutGuid = stockoutGuid; + } + + public String getStockoutGuid() + { + return stockoutGuid; + } + + public void setStockoutId(String stockoutId) + { + this.stockoutId = stockoutId; + } + + public String getStockoutId() + { + return stockoutId; + } + + public void setLotNo(String lotNo) + { + this.lotNo = lotNo; + } + + public String getLotNo() + { + return lotNo; + } + + public void setProductGuid(String productGuid) + { + this.productGuid = productGuid; + } + + public String getProductGuid() + { + return productGuid; + } + + public void setProductId(String productId) + { + this.productId = productId; + } + + public String getProductId() + { + return productId; + } + + public void setQuantity(BigDecimal quantity) + { + this.quantity = quantity; + } + + public BigDecimal getQuantity() + { + return quantity; + } + + public String getQuantityX() { + return quantityX; + } + + public void setQuantityX(String quantityX) { + this.quantityX = quantityX; + } + + public void setQuantityJ(BigDecimal quantityJ) + { + this.quantityJ = quantityJ; + } + + public BigDecimal getQuantityJ() + { + return quantityJ; + } + + public void setAssignNum(BigDecimal assignNum) + { + this.assignNum = assignNum; + } + + public BigDecimal getAssignNum() + { + return assignNum; + } + + public void setAssignNumX(BigDecimal assignNumX) + { + this.assignNumX = assignNumX; + } + + public BigDecimal getAssignNumX() + { + return assignNumX; + } + + public void setAssignNumJ(BigDecimal assignNumJ) + { + this.assignNumJ = assignNumJ; + } + + public BigDecimal getAssignNumJ() + { + return assignNumJ; + } + + public void setAllotQuantity(BigDecimal allotQuantity) + { + this.allotQuantity = allotQuantity; + } + + public BigDecimal getAllotQuantity() + { + return allotQuantity; + } + + public void setAllotQuantityX(BigDecimal allotQuantityX) + { + this.allotQuantityX = allotQuantityX; + } + + public BigDecimal getAllotQuantityX() + { + return allotQuantityX; + } + + public void setAllotQuantityJ(BigDecimal allotQuantityJ) + { + this.allotQuantityJ = allotQuantityJ; + } + + public BigDecimal getAllotQuantityJ() + { + return allotQuantityJ; + } + + public void setPrice(String price) + { + this.price = price; + } + + public String getPrice() + { + return price; + } + + public void setWarehouseId(String warehouseId) + { + this.warehouseId = warehouseId; + } + + public String getWarehouseId() + { + return warehouseId; + } + + public void setOutId(String outId) + { + this.outId = outId; + } + + public String getOutId() + { + return outId; + } + + public void setBukechaiQuantity(String bukechaiQuantity) + { + this.bukechaiQuantity = bukechaiQuantity; + } + + public String getBukechaiQuantity() + { + return bukechaiQuantity; + } + + public void setKechaiQuantity(String kechaiQuantity) + { + this.kechaiQuantity = kechaiQuantity; + } + + public String getKechaiQuantity() + { + return kechaiQuantity; + } + + public void setEntryid(String entryid) + { + this.entryid = entryid; + } + + public String getEntryid() + { + return entryid; + } + + public void setFlatQuantity(String flatQuantity) + { + this.flatQuantity = flatQuantity; + } + + public String getFlatQuantity() + { + return flatQuantity; + } + + public void setFid(String fid) + { + this.fid = fid; + } + + public String getFid() + { + return fid; + } + + public void setErpStockoutId(String erpStockoutId) + { + this.erpStockoutId = erpStockoutId; + } + + public String getErpStockoutId() + { + return erpStockoutId; + } + + public void setUnit(String unit) + { + this.unit = unit; + } + + public String getUnit() + { + return unit; + } + + public void setSpec(String spec) + { + this.spec = spec; + } + + public String getSpec() + { + return spec; + } + + public void setProductName(String productName) + { + this.productName = productName; + } + + public String getProductName() + { + return productName; + } + + public void setSpare1(String spare1) + { + this.spare1 = spare1; + } + + public String getSpare1() + { + return spare1; + } + + public void setSpare2(String spare2) + { + this.spare2 = spare2; + } + + public String getSpare2() + { + return spare2; + } + + public void setSpare3(String spare3) + { + this.spare3 = spare3; + } + + public String getSpare3() + { + return spare3; + } + + public void setSpare4(String spare4) + { + this.spare4 = spare4; + } + + public String getSpare4() + { + return spare4; + } + + public void setSpare5(String spare5) + { + this.spare5 = spare5; + } + + public String getSpare5() + { + return spare5; + } + + public void setSpare6(String spare6) + { + this.spare6 = spare6; + } + + public String getSpare6() + { + return spare6; + } + + public void setSpare7(String spare7) + { + this.spare7 = spare7; + } + + public String getSpare7() + { + return spare7; + } + + public void setSpare8(String spare8) + { + this.spare8 = spare8; + } + + public String getSpare8() + { + return spare8; + } + + public void setSpare9(String spare9) + { + this.spare9 = spare9; + } + + public String getSpare9() + { + return spare9; + } + + public void setSendStatus(String sendStatus) + { + this.sendStatus = sendStatus; + } + + public String getSendStatus() + { + return sendStatus; + } + + public void setSendTime(String sendTime) + { + this.sendTime = sendTime; + } + + public String getSendTime() + { + return sendTime; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public String getMsg() + { + return msg; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("stockoutDetailId", getStockoutDetailId()) + .append("stockoutGuid", getStockoutGuid()) + .append("stockoutId", getStockoutId()) + .append("lotNo", getLotNo()) + .append("productGuid", getProductGuid()) + .append("productId", getProductId()) + .append("quantity", getQuantity()) + .append("quantityX", getQuantityX()) + .append("quantityJ", getQuantityJ()) + .append("assignNum", getAssignNum()) + .append("assignNumX", getAssignNumX()) + .append("assignNumJ", getAssignNumJ()) + .append("allotQuantity", getAllotQuantity()) + .append("allotQuantityX", getAllotQuantityX()) + .append("allotQuantityJ", getAllotQuantityJ()) + .append("price", getPrice()) + .append("remark", getRemark()) + .append("warehouseId", getWarehouseId()) + .append("outId", getOutId()) + .append("bukechaiQuantity", getBukechaiQuantity()) + .append("kechaiQuantity", getKechaiQuantity()) + .append("entryid", getEntryid()) + .append("flatQuantity", getFlatQuantity()) + .append("fid", getFid()) + .append("erpStockoutId", getErpStockoutId()) + .append("unit", getUnit()) + .append("spec", getSpec()) + .append("productName", getProductName()) + .append("spare1", getSpare1()) + .append("spare2", getSpare2()) + .append("spare3", getSpare3()) + .append("spare4", getSpare4()) + .append("spare5", getSpare5()) + .append("spare6", getSpare6()) + .append("spare7", getSpare7()) + .append("spare8", getSpare8()) + .append("spare9", getSpare9()) + .append("sendStatus", getSendStatus()) + .append("sendTime", getSendTime()) + .append("msg", getMsg()) + .toString(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/mapper/OutStockoutDetailBackMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/mapper/OutStockoutDetailBackMapper.java new file mode 100644 index 0000000..bbc7b1c --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/mapper/OutStockoutDetailBackMapper.java @@ -0,0 +1,66 @@ +package com.ruoyi.out.outStockoutDetailBack.mapper; + +import java.util.List; +import com.ruoyi.out.outStockoutDetailBack.domain.OutStockoutDetailBack; +import org.apache.ibatis.annotations.Param; + +/** + * 历史出库单据子信息Mapper接口 + * + * @author ruoyi + * @date 2026-02-02 + */ +public interface OutStockoutDetailBackMapper +{ + /** + * 查询历史出库单据子信息 + * + * @param stockoutDetailId 历史出库单据子信息主键 + * @return 历史出库单据子信息 + */ + public OutStockoutDetailBack selectOutStockoutDetailBackByStockoutDetailId(String stockoutDetailId); + + /** + * 查询历史出库单据子信息列表 + * + * @param outStockoutDetailBack 历史出库单据子信息 + * @return 历史出库单据子信息集合 + */ + public List selectOutStockoutDetailBackList(OutStockoutDetailBack outStockoutDetailBack); + + /** + * 新增历史出库单据子信息 + * + * @param outStockoutDetailBack 历史出库单据子信息 + * @return 结果 + */ + public int insertOutStockoutDetailBack(OutStockoutDetailBack outStockoutDetailBack); + + /** + * 修改历史出库单据子信息 + * + * @param outStockoutDetailBack 历史出库单据子信息 + * @return 结果 + */ + public int updateOutStockoutDetailBack(OutStockoutDetailBack outStockoutDetailBack); + + /** + * 删除历史出库单据子信息 + * + * @param stockoutDetailId 历史出库单据子信息主键 + * @return 结果 + */ + public int deleteOutStockoutDetailBackByStockoutDetailId(String stockoutDetailId); + + /** + * 批量删除历史出库单据子信息 + * + * @param stockoutDetailIds 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteOutStockoutDetailBackByStockoutDetailIds(String[] stockoutDetailIds); + + void insertOutStockDetailBackFinish(@Param("list") List outStockoutDetailBacks); + + void deleteOutStockDetailList(@Param("list") List outStockoutDetailBacks); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/service/IOutStockoutDetailBackService.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/service/IOutStockoutDetailBackService.java new file mode 100644 index 0000000..d53dfb4 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/service/IOutStockoutDetailBackService.java @@ -0,0 +1,65 @@ +package com.ruoyi.out.outStockoutDetailBack.service; + +import java.util.List; +import com.ruoyi.out.outStockoutDetailBack.domain.OutStockoutDetailBack; + +/** + * 历史出库单据子信息Service接口 + * + * @author ruoyi + * @date 2026-02-02 + */ +public interface IOutStockoutDetailBackService +{ + /** + * 查询历史出库单据子信息 + * + * @param stockoutDetailId 历史出库单据子信息主键 + * @return 历史出库单据子信息 + */ + public OutStockoutDetailBack selectOutStockoutDetailBackByStockoutDetailId(String stockoutDetailId); + + /** + * 查询历史出库单据子信息列表 + * + * @param outStockoutDetailBack 历史出库单据子信息 + * @return 历史出库单据子信息集合 + */ + public List selectOutStockoutDetailBackList(OutStockoutDetailBack outStockoutDetailBack); + + /** + * 新增历史出库单据子信息 + * + * @param outStockoutDetailBack 历史出库单据子信息 + * @return 结果 + */ + public int insertOutStockoutDetailBack(OutStockoutDetailBack outStockoutDetailBack); + + /** + * 修改历史出库单据子信息 + * + * @param outStockoutDetailBack 历史出库单据子信息 + * @return 结果 + */ + public int updateOutStockoutDetailBack(OutStockoutDetailBack outStockoutDetailBack); + + /** + * 批量删除历史出库单据子信息 + * + * @param stockoutDetailIds 需要删除的历史出库单据子信息主键集合 + * @return 结果 + */ + public int deleteOutStockoutDetailBackByStockoutDetailIds(String[] stockoutDetailIds); + + /** + * 删除历史出库单据子信息信息 + * + * @param stockoutDetailId 历史出库单据子信息主键 + * @return 结果 + */ + public int deleteOutStockoutDetailBackByStockoutDetailId(String stockoutDetailId); + + void insertOutStockDetailBackFinish(List outStockoutDetailBacks); + + void deleteOutStockDetailList(List outStockoutDetailBacks); +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/service/impl/OutStockoutDetailBackServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/service/impl/OutStockoutDetailBackServiceImpl.java new file mode 100644 index 0000000..f3a730c --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/outStockoutDetailBack/service/impl/OutStockoutDetailBackServiceImpl.java @@ -0,0 +1,103 @@ +package com.ruoyi.out.outStockoutDetailBack.service.impl; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.out.outStockoutDetailBack.mapper.OutStockoutDetailBackMapper; +import com.ruoyi.out.outStockoutDetailBack.domain.OutStockoutDetailBack; +import com.ruoyi.out.outStockoutDetailBack.service.IOutStockoutDetailBackService; + +/** + * 历史出库单据子信息Service业务层处理 + * + * @author ruoyi + * @date 2026-02-02 + */ +@Service +public class OutStockoutDetailBackServiceImpl implements IOutStockoutDetailBackService +{ + @Autowired + private OutStockoutDetailBackMapper outStockoutDetailBackMapper; + + /** + * 查询历史出库单据子信息 + * + * @param stockoutDetailId 历史出库单据子信息主键 + * @return 历史出库单据子信息 + */ + @Override + public OutStockoutDetailBack selectOutStockoutDetailBackByStockoutDetailId(String stockoutDetailId) + { + return outStockoutDetailBackMapper.selectOutStockoutDetailBackByStockoutDetailId(stockoutDetailId); + } + + /** + * 查询历史出库单据子信息列表 + * + * @param outStockoutDetailBack 历史出库单据子信息 + * @return 历史出库单据子信息 + */ + @Override + public List selectOutStockoutDetailBackList(OutStockoutDetailBack outStockoutDetailBack) + { + return outStockoutDetailBackMapper.selectOutStockoutDetailBackList(outStockoutDetailBack); + } + + /** + * 新增历史出库单据子信息 + * + * @param outStockoutDetailBack 历史出库单据子信息 + * @return 结果 + */ + @Override + public int insertOutStockoutDetailBack(OutStockoutDetailBack outStockoutDetailBack) + { + return outStockoutDetailBackMapper.insertOutStockoutDetailBack(outStockoutDetailBack); + } + + /** + * 修改历史出库单据子信息 + * + * @param outStockoutDetailBack 历史出库单据子信息 + * @return 结果 + */ + @Override + public int updateOutStockoutDetailBack(OutStockoutDetailBack outStockoutDetailBack) + { + return outStockoutDetailBackMapper.updateOutStockoutDetailBack(outStockoutDetailBack); + } + + /** + * 批量删除历史出库单据子信息 + * + * @param stockoutDetailIds 需要删除的历史出库单据子信息主键 + * @return 结果 + */ + @Override + public int deleteOutStockoutDetailBackByStockoutDetailIds(String[] stockoutDetailIds) + { + return outStockoutDetailBackMapper.deleteOutStockoutDetailBackByStockoutDetailIds(stockoutDetailIds); + } + + /** + * 删除历史出库单据子信息信息 + * + * @param stockoutDetailId 历史出库单据子信息主键 + * @return 结果 + */ + @Override + public int deleteOutStockoutDetailBackByStockoutDetailId(String stockoutDetailId) + { + return outStockoutDetailBackMapper.deleteOutStockoutDetailBackByStockoutDetailId(stockoutDetailId); + } + + @Override + public void insertOutStockDetailBackFinish(List outStockoutDetailBacks) { + outStockoutDetailBackMapper.insertOutStockDetailBackFinish(outStockoutDetailBacks); + } + + @Override + public void deleteOutStockDetailList(List outStockoutDetailBacks) { + outStockoutDetailBackMapper.deleteOutStockDetailList(outStockoutDetailBacks); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/out/productAndStock/controller/ViewProductAndStockController.java b/ruoyi-admin/src/main/java/com/ruoyi/out/productAndStock/controller/ViewProductAndStockController.java index e536960..90f41d4 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/out/productAndStock/controller/ViewProductAndStockController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/out/productAndStock/controller/ViewProductAndStockController.java @@ -35,7 +35,7 @@ public class ViewProductAndStockController extends BaseController private IViewProductAndStockService viewProductAndStockService; /** - * 查询库存物资列表 +// * 查询库存物资列表 */ @PreAuthorize("@ss.hasPermi('productAndStock:productAndStock:list')") @GetMapping("/list") diff --git a/ruoyi-admin/src/main/java/com/ruoyi/pda/controller/PdaController.java b/ruoyi-admin/src/main/java/com/ruoyi/pda/controller/PdaController.java index 2c2cb57..21167df 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/pda/controller/PdaController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/pda/controller/PdaController.java @@ -2,26 +2,42 @@ package com.ruoyi.pda.controller; import com.ruoyi.api.domain.RequestEnter; import com.ruoyi.api.domain.WcsPort; +import com.ruoyi.bas.agvPoint.domain.AgvPoint; +import com.ruoyi.bas.agvPoint.domain.AgvTask; +import com.ruoyi.bas.agvPoint.service.impl.AgvPointServiceImpl; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.device.agv.domain.AgvContainerTask; +import com.ruoyi.device.agv.service.IAgvContainerTaskService; import com.ruoyi.in.stockindetail.domain.InStockinDetail; import com.ruoyi.in.stockindetail.service.IInStockinDetailService; +import com.ruoyi.job.mydojob.domain.MydoJob; +import com.ruoyi.job.mydojob.service.IMydoJobService; +import com.ruoyi.job.mydojobdetail.domain.MydoJobDetail; +import com.ruoyi.out.outStockout.domain.OutStockout; +import com.ruoyi.out.outStockout.service.impl.OutStockoutServiceImpl; +import com.ruoyi.out.outStockoutDetail.domain.OutStockoutDetail; +import com.ruoyi.out.outStockoutDetail.service.impl.OutStockoutDetailServiceImpl; import com.ruoyi.pda.domain.TrayCodeMakeSure; import com.ruoyi.pda.domain.TrayCodeMsg; +import com.ruoyi.pda.mapper.PdaMapper; import com.ruoyi.pda.service.PdaService; import com.ruoyi.stock.stock.domain.BasStock; +import com.ruoyi.stock.stock.service.IBasStockService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; +import java.util.HashMap; import java.util.List; +import java.util.UUID; @Controller @RequestMapping("/pda") @@ -32,6 +48,20 @@ public class PdaController extends BaseController { private PdaService pdaService; @Autowired private IInStockinDetailService iInStockinDetailService; + @Autowired + private OutStockoutServiceImpl outStockoutService; + @Autowired + private OutStockoutDetailServiceImpl outStockoutDetailService; + @Autowired + private AgvPointServiceImpl agvPointService; + @Autowired + private IAgvContainerTaskService agvContainerTaskService; + @Autowired + private PdaMapper pdaMapper; + @Autowired + private IMydoJobService mydoJobService; + @Autowired + private IBasStockService basStockService; /** * 查询是否有半满托盘 @@ -46,11 +76,11 @@ public class PdaController extends BaseController { /** * 通过单据码查询物料详情 */ - @RequestMapping("/selectDetailById") + @RequestMapping("/selectDetailByIds") @ResponseBody - public AjaxResult selectDetailById(String inStockinDetailId) { + public AjaxResult selectDetailByIds(String inStockinDetailId) { InStockinDetail inStockinDetail = iInStockinDetailService.selectInStockinDetailByStockinDetailId(inStockinDetailId); - if(inStockinDetail != null) { + if (inStockinDetail != null) { inStockinDetail.setQuantity(String.valueOf(Integer.valueOf(inStockinDetail.getQuantity()) - Integer.valueOf(inStockinDetail.getScanNum()))); } return AjaxResult.success(inStockinDetail); @@ -67,6 +97,22 @@ public class PdaController extends BaseController { } + /** + * 通过单据码查询物料详情 TODO 修改单据码为barCode 前端需同步修改 + */ + @RequestMapping("/selectDetailById") + @ResponseBody + public AjaxResult selectDetailById(String barCode) { + List stockinDetails = iInStockinDetailService.selectStockInByDetailByBarCode(barCode); + stockinDetails.stream().forEach(inStockinDetail -> { + Integer quantity = StringUtils.hasText(inStockinDetail.getQuantity()) ? Integer.valueOf(inStockinDetail.getQuantity()) : 0; + Integer scanNum = StringUtils.hasText(inStockinDetail.getScanNum()) ? Integer.valueOf(inStockinDetail.getScanNum()) : 0; + inStockinDetail.setQuantity(String.valueOf(quantity - scanNum)); + }); + return AjaxResult.success(stockinDetails); + } + + /** * 通过托盘码查询作业或trayMsg */ @@ -85,13 +131,20 @@ public class PdaController extends BaseController { return pdaService.bindTray(trayCodeMakeSure); } + @RequestMapping("/bindTray2") + @ResponseBody + public AjaxResult bindTray2(@RequestBody TrayCodeMakeSure trayCodeMakeSure) { + return pdaService.bindTray2(trayCodeMakeSure); + } + + /** * 空托盘入库 */ @RequestMapping("/tpIn") @ResponseBody public AjaxResult tpIn(@RequestBody TrayCodeMsg trayCodeMsg) { - return pdaService.tpIn(trayCodeMsg.getTrayCode()); + return pdaService.tpIn(trayCodeMsg); } /** @@ -105,12 +158,13 @@ public class PdaController extends BaseController { /** * 出库确认查询子作业信息 + * * @param trayCodeMsg * @return */ @RequestMapping("/selectJobDetailByTray") @ResponseBody - public AjaxResult selectJobDetailByTray(@RequestBody TrayCodeMsg trayCodeMsg){ + public AjaxResult selectJobDetailByTray(@RequestBody TrayCodeMsg trayCodeMsg) { return pdaService.selectJobDetailByTray(trayCodeMsg); } @@ -129,9 +183,6 @@ public class PdaController extends BaseController { } - - - /** * 入库扫码生成作业 */ @@ -142,7 +193,6 @@ public class PdaController extends BaseController { } - @RequestMapping("/selectDetailByPDTray") @ResponseBody public AjaxResult selectDetailByPDTray(@RequestBody TrayCodeMakeSure trayCodeMakeSure) { @@ -150,9 +200,6 @@ public class PdaController extends BaseController { } - - - /** * 盘点出库确认 * @@ -161,7 +208,7 @@ public class PdaController extends BaseController { */ @PreAuthorize("@ss.hasPermi('pda:check:checkMakeSure')") @PostMapping("/checkMakeSure") - @Log(title = "手持机盘点出库确认", businessType = BusinessType.INSERT) + @Log(title = "手持机盘点出库确认", businessType = BusinessType.OTHER) @ResponseBody public AjaxResult checkMakeSure(@RequestBody TrayCodeMakeSure trayCodeMakeSure) { return pdaService.checkMakeSure(trayCodeMakeSure); @@ -179,6 +226,245 @@ public class PdaController extends BaseController { return pdaService.updateWcsPort(wcsPort); } + @RequestMapping("/hcoutMakesure") + @ResponseBody + @Log(title = "手持机缓存出库确认", businessType = BusinessType.OTHER) + public AjaxResult hcoutMakesure(String trayCode) { + + return pdaService.hcoutMakesure(trayCode); + } + + + /** + * 平库入库 + */ + @RequestMapping("/inStockPk") + @ResponseBody + public AjaxResult inStockPk(@RequestBody TrayCodeMakeSure trayCodeMakeSure) { + return pdaService.completeInPk(trayCodeMakeSure); + } + + /** + * 库存查询(平库扫码查询托盘入库信息) + */ + @RequestMapping("/searchStock") + @ResponseBody + public AjaxResult searchStock(@RequestBody TrayCodeMakeSure trayCodeMakeSure) { + + return pdaService.selectBasStockHc(trayCodeMakeSure.getTrayCode()); + } + + /** + * 立库出库信息校验 + * + * @param trayCodeMakeSure + * @return + */ + @RequestMapping("/verifyMaterial") + @ResponseBody + public AjaxResult verifyMaterial(@RequestBody TrayCodeMakeSure trayCodeMakeSure) { + String trayCode = trayCodeMakeSure.getTrayCode(); + List mydoJobDetailList = trayCodeMakeSure.getMydoJobDetailList(); + for (MydoJobDetail m : mydoJobDetailList) { + Integer count = pdaService.selectByTrayCodeAndProduct(trayCode, m.getProductId()); + if (count == 0) { + return AjaxResult.error(m.getProductId() + ",物料不是出库物料"); + } + } + + return AjaxResult.success(); + } + + /** + * 平库出库确认 + * + * @param trayCodeMakeSure + * @return + */ + @RequestMapping("/completeOutPk") + @ResponseBody + @Async + @Transactional(rollbackFor = Exception.class) + public AjaxResult completeOutPk(@RequestBody TrayCodeMakeSure trayCodeMakeSure) { + try { + String trayCode = trayCodeMakeSure.getTrayCode(); + List mydoJobDetailList = trayCodeMakeSure.getMydoJobDetailList(); + for (MydoJobDetail m : mydoJobDetailList) { + HashMap map = new HashMap<>(); + map.put("v_tray_code", trayCode); + map.put("v_out_stockout_detail_id", trayCodeMakeSure.getStockoutDetailId()); + map.put("v_quantity", m.getOutQuantity()); + map.put("v_stock_id", m.getStockId()); + pdaService.completeOutPk(map); + Integer vResult = (Integer) map.get("v_result"); + if (vResult != 10) { + System.err.println(map.get("v_result_msg").toString()); + return AjaxResult.error(map.get("v_result_msg").toString()); + } + } + return AjaxResult.success(); + } catch (Exception e) { + throw new RuntimeException(e.getMessage()); + } + } + + + /** + * 查询平库出库主单 建议参数(erpStockOutId U8单据号作为查询条件传到后台) + * + * @param outStockout + * @return + */ + @RequestMapping("/OutFillPk") + @ResponseBody + + public AjaxResult OutFillPk() { + OutStockout outStockout = new OutStockout(); + outStockout.setWarehouseId("2"); + outStockoutService.selectOutStockoutList(outStockout); + return AjaxResult.success(outStockoutService.selectOutStockoutList(outStockout)); + } + + + /** + * 查出平库出库子单 参数: stockoutId 作为参数传递到后台 + * + * @param outStockout + * @return + */ + @RequestMapping("/OutFillPkDetail") + @ResponseBody + public AjaxResult OutFillPkDetail(@RequestBody OutStockout outStockout) { + + List outStockouts = outStockoutService.selectOutStockoutList(outStockout); + + return AjaxResult.success(outStockoutDetailService.selectOutStockoutDetailByStockoutGuid(outStockouts.get(0).getStockoutGuid())); + } + + + /** + * 查询平库出库子单对应信息 在平库中是否存在 + * 参数:trayCode 托盘码 + * 参数:stockinDetailId 子单据号 + * + * @param trayCodeMsg + * @return + */ + @RequestMapping("/queryBasStockHc") + @ResponseBody + public AjaxResult queryBasStockHc(@RequestBody TrayCodeMsg trayCodeMsg) { + return pdaService.selectBasStockHcs(trayCodeMsg.getTrayCode(), trayCodeMsg.getStockoutDetailId()); + } + + // 立库扫码规则校验 + @RequestMapping("/validateMaterial") + @ResponseBody + public AjaxResult validateMaterial(@RequestBody TrayCodeMakeSure trayCodeMakeSure) { + HashMap map = new HashMap<>(); + map.put("v_tray_code", trayCodeMakeSure.getTrayCode()); + map.put("v_stockin_detail_id", trayCodeMakeSure.getInStockinDetailId()); + map.put("v_is_bound_accord", trayCodeMakeSure.getIsBoundByAccord()); + map.put("v_quantity", trayCodeMakeSure.getQuantity()); + pdaMapper.bindTray(map); + if (!"10".equals(map.get("v_result").toString())) { + return AjaxResult.error(map.get("v_result").toString()); + } else { + return AjaxResult.success(map.get("v_result").toString()); + } + } + + + /** + * 平库出库信息校验 + * + * @param trayCodeMakeSure TODO 要校验项目号,批号,以及其他条件,要复合查询,待修改 + * @return + */ + @RequestMapping("/verifypkTrayMaterials") + @ResponseBody + public AjaxResult verifypkTrayMaterials(@RequestBody TrayCodeMakeSure trayCodeMakeSure) { + String trayCode = trayCodeMakeSure.getTrayCode(); + List mydoJobDetailList = trayCodeMakeSure.getMydoJobDetailList(); + for (MydoJobDetail m : mydoJobDetailList) { + String productId = m.getProductId(); + Integer integer = pdaService.selectBasStockHcCount(trayCode, productId); + if (integer == 0) { + return AjaxResult.error(m.getProductId() + ",物料不是出库物料"); + } + } + return AjaxResult.success(); + } + + + // 查询AGV的起点和终点 + @RequestMapping("/selectAgvPointByType") + @ResponseBody + public AjaxResult selectAgvPointByType(String type) { + AgvPoint agvPoint = new AgvPoint(); + agvPoint.setType(type); + List agvPoints = agvPointService.selectAgvPointList(agvPoint); + return AjaxResult.success(agvPoints); + } + + // 保存agv执行队列 + @RequestMapping("/insertAgvJob") + @ResponseBody + public AjaxResult insertAgvJob(@RequestBody AgvTask agvTask) { + AgvPoint agvPoint = new AgvPoint(); + agvPoint.setStation(agvTask.getEndPoint()); + List agvPoints = agvPointService.selectAgvPointList(agvPoint); + if (!agvPoints.get(0).getStation().equals("K1-1") && !agvPoints.get(0).getStation().equals("K2-1") && agvPoints.get(0).getSpare1().equals("2")) { + return AjaxResult.error("该点位被占用,请检查!"); + } + AgvContainerTask agvContainerTask = new AgvContainerTask(); + agvContainerTask.setContainer(UUID.randomUUID().toString()); + agvContainerTask.setEndPoint(agvTask.getEndPoint()); + agvContainerTask.setStartPoint(agvTask.getStartPoint()); + agvContainerTask.setSpare1(agvTask.getType()); + agvContainerTask.setSpare2(agvTask.getTrayCode()); + agvContainerTask.setStatus("0"); + agvContainerTaskService.insertAgvContainerTask(agvContainerTask); + return AjaxResult.success(); + } + + + // 保存agv执行队列 + @GetMapping("/selectAgvPointByType") + @ResponseBody + public AjaxResult selectAgvPointByType(String type, String position) { + System.out.println(type + " " + position); + AgvPoint agvPoint = new AgvPoint(); +// agvPoint.setType(type); + agvPoint.setStation(position); + List agvPoints = agvPointService.selectAgvPointList(agvPoint); + + + return AjaxResult.success(agvPoints); + } + + +// // 查询子单据的明细信息 +// @RequestMapping("/selectDetailById") +// public AjaxResult selectDetailById(@RequestBody TrayCodeMakeSure trayCodeMakeSure) { +// String inStockinDetailId = trayCodeMakeSure.getInStockinDetailId(); +// InStockinDetail inStockinDetail = iInStockinDetailService.selectInStockinDetailByStockinDetailId(inStockinDetailId); +// return AjaxResult.success(inStockinDetail); +// +// } + + @RequestMapping("/selectByTrayCode") + public AjaxResult selectByTrayCode(@RequestBody TrayCodeMakeSure trayCodeMakeSure) { + MydoJob mydoJob = mydoJobService.selectMydoJobByTrayCode(trayCodeMakeSure.getTrayCode()); + if (mydoJob != null && mydoJob.getInOrOut().equals("26")) { + BasStock basStock = basStockService.selectBasStockListTopOne(trayCodeMakeSure.getTrayCode()); + return AjaxResult.success(basStock); + } else { + return AjaxResult.error("该托盘无盘任务"); + } + + + } + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/pda/domain/TrayCodeMakeSure.java b/ruoyi-admin/src/main/java/com/ruoyi/pda/domain/TrayCodeMakeSure.java index 3e30ebe..566b676 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/pda/domain/TrayCodeMakeSure.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/pda/domain/TrayCodeMakeSure.java @@ -22,10 +22,17 @@ public class TrayCodeMakeSure { private String exitId; private String isFull; + // 选中传1 没选中传0 + private String isBoundByAccord; //拣选详情列表 private List mydoJobDetailList; //盘点详情列表 private List materials; //异常详情列表 private List materialDetails; + private String quantity; + private String stockinDetailId; + private String inStockinDetailId; + private String stockoutDetailId; + private String cargoSpaceId; } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/pda/domain/TrayCodeMsg.java b/ruoyi-admin/src/main/java/com/ruoyi/pda/domain/TrayCodeMsg.java index ef453f3..71cb587 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/pda/domain/TrayCodeMsg.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/pda/domain/TrayCodeMsg.java @@ -1,5 +1,7 @@ package com.ruoyi.pda.domain; +import java.util.List; + public class TrayCodeMsg { private String trayCode; @@ -18,6 +20,26 @@ private String stockinDetailId; private String inOut; private String status; +private String stockoutDetailId; + + + public String getStockoutDetailId() { + return stockoutDetailId; + } + + public void setStockoutDetailId(String stockoutDetailId) { + this.stockoutDetailId = stockoutDetailId; + } + + private String trayType; + + public String getTrayType() { + return trayType; + } + + public void setTrayType(String trayType) { + this.trayType = trayType; + } public String getStatus() { return status; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/pda/mapper/PdaMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/pda/mapper/PdaMapper.java index 64290a8..4721310 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/pda/mapper/PdaMapper.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/pda/mapper/PdaMapper.java @@ -38,4 +38,18 @@ public interface PdaMapper { void pkOut(HashMap map); void outMakeSureException(HashMap map); + + void hcoutMakesure(HashMap map); + + Integer selectByTrayCodeAndProduct(String trayCode, String productId); + + void completeOutPk(HashMap map); + + void completeInPk(HashMap map); + + void FillFinishAllot(HashMap map); + + void FillFinishAllotOut(HashMap map); + + void bindTrayCheck(HashMap map); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/pda/service/PdaService.java b/ruoyi-admin/src/main/java/com/ruoyi/pda/service/PdaService.java index 767242a..2b29890 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/pda/service/PdaService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/pda/service/PdaService.java @@ -8,6 +8,7 @@ import com.ruoyi.pda.domain.TrayCodeMakeSure; import com.ruoyi.pda.domain.TrayCodeMsg; import com.ruoyi.stock.stock.domain.BasStock; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -28,7 +29,7 @@ public interface PdaService { AjaxResult bindTray(TrayCodeMakeSure trayCodeMakeSure); - AjaxResult tpIn(String trayCode); + AjaxResult tpIn(TrayCodeMsg trayCodeMsg); AjaxResult tpOut(TrayCodeMsg trayCodeMsg); @@ -56,4 +57,19 @@ public interface PdaService { AjaxResult updateWcsPort(WcsPort wcsport); + AjaxResult hcoutMakesure(String trayCode); + + AjaxResult completeInPk(TrayCodeMakeSure trayCodeMakeSure); + + AjaxResult selectBasStockHc(String trayCode); + + Integer selectByTrayCodeAndProduct(String trayCode, String productId); + + void completeOutPk(HashMap map); + + Integer selectBasStockHcCount(String trayCode, String productId); + + AjaxResult selectBasStockHcs(String trayCode, String stockoutDetailId); + + AjaxResult bindTray2(TrayCodeMakeSure trayCodeMakeSure); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/pda/service/PdaServiceImp.java b/ruoyi-admin/src/main/java/com/ruoyi/pda/service/PdaServiceImp.java index ba4607b..cfe8dab 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/pda/service/PdaServiceImp.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/pda/service/PdaServiceImp.java @@ -6,12 +6,12 @@ import com.ruoyi.api.domain.RequestEnter; import com.ruoyi.api.domain.WcsPort; import com.ruoyi.api.service.IToWcsService; import com.ruoyi.api.service.IToWmsService; +import com.ruoyi.algorithm.wms.OutboundWorkflowCoordinator; import com.ruoyi.check.commit.domain.CheckCommitRecord; import com.ruoyi.check.commit.service.ICheckCommitRecordService; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.MessageUtils; -import com.ruoyi.in.stockin.domain.InStockin; import com.ruoyi.in.stockin.service.IInStockinService; import com.ruoyi.in.stockindetail.domain.InStockinDetail; import com.ruoyi.in.stockindetail.service.IInStockinDetailService; @@ -19,7 +19,8 @@ import com.ruoyi.job.mydojob.domain.MydoJob; import com.ruoyi.job.mydojob.service.IMydoJobService; import com.ruoyi.job.mydojobdetail.domain.MydoJobDetail; import com.ruoyi.job.mydojobdetail.service.IMydoJobDetailService; -import com.ruoyi.job.mydojobdetail.service.impl.MydoJobDetailServiceImpl; +import com.ruoyi.out.outStockoutDetail.domain.OutStockoutDetail; +import com.ruoyi.out.outStockoutDetail.service.impl.OutStockoutDetailServiceImpl; import com.ruoyi.pda.domain.TrayCodeMakeSure; import com.ruoyi.pda.domain.TrayCodeMsg; import com.ruoyi.pda.mapper.PdaMapper; @@ -34,6 +35,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; +import java.util.stream.Collectors; @Service @Slf4j @@ -60,13 +62,16 @@ public class PdaServiceImp implements PdaService { private BasStockMapper basStockMapper; @Autowired private IInStockinService inStockinService; - + @Autowired + private OutStockoutDetailServiceImpl outStockoutDetailService; + @Autowired + private OutboundWorkflowCoordinator outboundWorkflowCoordinator; @Override public List selectHasHalfTray(String inStockinDetailId) { InStockinDetail inStockinDetail = inStockinDetailService.selectInStockinDetailByStockinDetailId(inStockinDetailId); - InStockin inStockin = inStockinService.selectInStockinByStockinId(inStockinDetail.getStockinId()); - inStockinDetail.setSpare4(inStockin.getDepartmentNo()); +// InStockin inStockin = inStockinService.selectInStockinByStockinId(inStockinDetail.getStockinId()); +// inStockinDetail.setSpare4(inStockinDetail.getSpare4()); List hasHalfTray = basStockMapper.selectHasHalfTray(inStockinDetail); return hasHalfTray; } @@ -75,16 +80,16 @@ public class PdaServiceImp implements PdaService { @Override public AjaxResult halfTrayOut(TrayCodeMsg trayCodeMsg) { InStockinDetail inStockinDetail = inStockinDetailService.selectInStockinDetailByStockinDetailId(trayCodeMsg.getStockinDetailId()); - InStockin inStockin = inStockinService.selectInStockinByStockinId(inStockinDetail.getStockinId()); - inStockinDetail.setSpare4(inStockin.getDepartmentNo()); +// InStockin inStockin = inStockinService.selectInStockinByStockinId(inStockinDetail.getStockinId()); +// inStockinDetail.setSpare4(inStockin.getDepartmentNo()); List hasHalfTray = basStockMapper.selectHasHalfTray(inStockinDetail); HashMap map = new HashMap<>(); map.put("v_tray_code", hasHalfTray.get(0).getTrayCode()); - map.put("v_exit_id",trayCodeMsg.getExitId()); + map.put("v_exit_id", trayCodeMsg.getExitId()); pdaMapper.halfTrayOut(map); - if(!"10".equals(map.get("v_result").toString())){ + if (!"10".equals(map.get("v_result").toString())) { return AjaxResult.error(map.get("v_resultmsg").toString()); - }else{ + } else { return AjaxResult.success(); } @@ -112,21 +117,18 @@ public class PdaServiceImp implements PdaService { @Transactional(rollbackFor = Exception.class) public AjaxResult bindTray(TrayCodeMakeSure trayCodeMakeSure) { StringBuilder errorbulider = new StringBuilder(); - - for (MydoJobDetail mydoJobDetail : trayCodeMakeSure.getMydoJobDetailList()) { HashMap map = new HashMap<>(); map.put("v_tray_code", trayCodeMakeSure.getTrayCode()); map.put("v_stockin_detail_id", mydoJobDetail.getStockinDetailId()); + map.put("v_is_bound_accord", trayCodeMakeSure.getIsBoundByAccord()); map.put("v_quantity", Integer.valueOf(mydoJobDetail.getInQuantity())); pdaMapper.bindTray(map); if (!"10".equals(map.get("v_result").toString())) { errorbulider.append(mydoJobDetail.getStockinDetailId() + map.get("v_resultmsg").toString()); return AjaxResult.error(errorbulider.toString()); } - } - HashMap map = new HashMap<>(); map.put("v_tray_code", trayCodeMakeSure.getTrayCode()); map.put("v_is_full", trayCodeMakeSure.getIsFull()); @@ -134,18 +136,19 @@ public class PdaServiceImp implements PdaService { if (!"10".equals(map.get("v_result").toString())) { return AjaxResult.error(errorbulider.toString()); } - return AjaxResult.success(); } @Override - public AjaxResult tpIn(String trayCode) { + public AjaxResult tpIn(TrayCodeMsg trayCodeMsg) { HashMap map = new HashMap<>(); - map.put("v_tray_code", trayCode); + map.put("v_tray_code", trayCodeMsg.getTrayCode()); + map.put("v_tray_type", trayCodeMsg.getTrayType()); + map.put("v_quantity", Integer.valueOf(trayCodeMsg.getInQuantity())); pdaMapper.tpIn(map); - if(!"10".equals(map.get("v_result").toString())){ + if (!"10".equals(map.get("v_result").toString())) { return AjaxResult.error(map.get("v_resultmsg").toString()); - }else{ + } else { return AjaxResult.success(); } @@ -155,11 +158,11 @@ public class PdaServiceImp implements PdaService { public AjaxResult tpOut(TrayCodeMsg trayCodeMsg) { HashMap map = new HashMap<>(); - map.put("v_exit_id", trayCodeMsg.getExitId()); + map.put("v_tray_type", trayCodeMsg.getTrayType()); pdaMapper.tpOut(map); - if(!"10".equals(map.get("v_result").toString())){ + if (!"10".equals(map.get("v_result").toString())) { return AjaxResult.error(map.get("v_resultmsg").toString()); - }else{ + } else { return AjaxResult.success(); } } @@ -175,8 +178,9 @@ public class PdaServiceImp implements PdaService { } @Override + @Transactional(rollbackFor = Exception.class) public AjaxResult addInJob(RequestEnter requestEnter) { - if (requestEnter.getEntranceId() != null) { + if (StrUtil.isNotBlank(requestEnter.getEntranceId())) { MydoJob mydoJob = new MydoJob(); mydoJob.setEntranceId(requestEnter.getEntranceId()); mydoJob.setStatus("1"); @@ -189,6 +193,17 @@ public class PdaServiceImp implements PdaService { } requestEnter.setFlag("1"); AjaxResult ajaxResult = iToWmsService.requestEnterByTrayCode(requestEnter); + if (!ajaxResult.isSuccess()) { + return ajaxResult; + } + Object data = ajaxResult.get(AjaxResult.DATA_TAG); + if (!(data instanceof MydoJob trayJob)) { + return AjaxResult.error("该条码无入库任务,请扫码绑定!"); + } + trayJob.setEntranceId(requestEnter.getEntranceId()); + if (mydoJobService.updateMydoJob(trayJob) != 1) { + return AjaxResult.error("入库作业入口更新失败"); + } return ajaxResult; } @@ -197,14 +212,16 @@ public class PdaServiceImp implements PdaService { @Override public AjaxResult selectDetailByPDTray(TrayCodeMakeSure trayCodeMakeSure) { MydoJob mydoJob = new MydoJob(); - mydoJob.setExitId(trayCodeMakeSure.getExitId()); +// mydoJob.setExitId(trayCodeMakeSure.getExitId()); mydoJob.setStatus("3"); - mydoJob.setInOrOut("26"); + mydoJob.setInOrOut("28"); + mydoJob.setTrayCode(trayCodeMakeSure.getTrayCode()); List mydoJobDetails = mydoJobDetailService.selectPdMydoJobDetailListByExit(mydoJob); return AjaxResult.success(mydoJobDetails); } @Override + @Transactional(rollbackFor = Exception.class) public AjaxResult outMakeSure(TrayCodeMakeSure trayCodeMakeSure) { String trayCode = trayCodeMakeSure.getTrayCode(); // String[] split = trayCode.split(" "); @@ -223,6 +240,7 @@ public class PdaServiceImp implements PdaService { pdaMapper.outMakeSure(map); String result = map.get("v_result").toString(); if ("10".equals(result)) { + outboundWorkflowCoordinator.confirmOutbound(trayCode); return AjaxResult.success(); } else { return AjaxResult.error(map.get("v_resultmsg").toString()); @@ -237,9 +255,9 @@ public class PdaServiceImp implements PdaService { public AjaxResult checkMakeSure(TrayCodeMakeSure trayCodeMakeSure) { MydoJob mydoJob = new MydoJob(); - mydoJob.setExitId(trayCodeMakeSure.getExitId()); + mydoJob.setTrayCode(trayCodeMakeSure.getTrayCode()); mydoJob.setStatus("3"); - mydoJob.setInOrOut("26"); + mydoJob.setInOrOut("28"); List mydoJobDetails = mydoJobDetailService.selectPdMydoJobDetailListByExit(mydoJob); if (mydoJobDetails.isEmpty()) { return AjaxResult.error("该物料没有盘点出库作业,请检查"); @@ -249,7 +267,7 @@ public class PdaServiceImp implements PdaService { if (CollUtil.isNotEmpty(mydoJobDetailList)) { boolean flag = mydoJobDetailList.stream().anyMatch(x -> StrUtil.isEmpty(x.getStockId()) && "0".equals(x.getInQuantity())); if (flag) { - return AjaxResult.warn(MessageUtils.message("warn.message8")); + return AjaxResult.warn(MessageUtils.message("盘点数量不可为0")); } for (MydoJobDetail mydoJobDetail : mydoJobDetailList) { //插入盘点提交表 @@ -287,4 +305,100 @@ public class PdaServiceImp implements PdaService { AjaxResult ajaxResult = toWcsService.updateWcsPort(wcsport); return ajaxResult; } + + @Override + public AjaxResult hcoutMakesure(String trayCode) { + HashMap map = new HashMap<>(); + map.put("v_tray_code", trayCode); + pdaMapper.hcoutMakesure(map); + String result = map.get("v_result").toString(); + if ("10".equals(result)) { + return AjaxResult.success(); + } else { + return AjaxResult.error(map.get("v_resultmsg").toString()); + } + } + + + @Override + public AjaxResult completeInPk(TrayCodeMakeSure trayCodeMakeSure) { + HashMap map = new HashMap<>(); + map.put("v_tray_code", trayCodeMakeSure.getTrayCode()); + map.put("v_in_stockin_detail_id", trayCodeMakeSure.getStockinDetailId()); + map.put("v_quantity", trayCodeMakeSure.getQuantity()); + map.put("v_cargo_space_id", trayCodeMakeSure.getCargoSpaceId()); + pdaMapper.completeInPk(map); + String result = map.get("v_result").toString(); + if ("10".equals(result)) { + return AjaxResult.success(); + } else { + return AjaxResult.error(map.get("v_resultmsg").toString()); + } + } + + @Override + public AjaxResult selectBasStockHc(String trayCode) { + BasStock basStock = new BasStock(); + basStock.setTrayCode(trayCode); + List stocks = basStockMapper.selectBasStockListHc(basStock); + if (stocks.size() > 0) { + return AjaxResult.success(stocks); + } else { + return AjaxResult.error("无库存信息"); + } + } + + @Override + public Integer selectByTrayCodeAndProduct(String trayCode, String productId) { + return pdaMapper.selectByTrayCodeAndProduct(trayCode, productId); + } + + @Override + public void completeOutPk(HashMap map) { + pdaMapper.completeOutPk(map); + } + + @Override + public Integer selectBasStockHcCount(String trayCode, String productId) { + BasStock basStock = new BasStock(); + basStock.setTrayCode(trayCode); + basStock.setProductId(productId); + List basStocks = basStockMapper.selectBasStockHcCount(basStock); + return basStocks.size(); + } + + @Override + public AjaxResult selectBasStockHcs(String trayCode, String stockoutDetailId) { + OutStockoutDetail outStockoutDetail = outStockoutDetailService.selectOutStockoutDetailByStockoutDetailId(stockoutDetailId); + List stocks = basStockMapper.selectBasStockHcs(trayCode, outStockoutDetail); + if (stocks.size() > 0) { + return AjaxResult.success(stocks); + } + { + return AjaxResult.error("该托盘无对应库存,请检查!"); + } + } + + @Override + public AjaxResult bindTray2(TrayCodeMakeSure trayCodeMakeSure) { + String collect = trayCodeMakeSure.getMydoJobDetailList().stream().map(detail -> detail.getStockinDetailId() + ":" + detail.getInQuantity()).collect(Collectors.joining(",")); + HashMap map = new HashMap<>(); + map.put("v_tray_code", trayCodeMakeSure.getTrayCode()); + map.put("v_string", collect); + map.put("v_is_bound_accord", trayCodeMakeSure.getIsBoundByAccord()); + pdaMapper.bindTray(map); + if (!"10".equals(map.get("v_result").toString())) { + return AjaxResult.error(map.get("v_result").toString()); + } + map.clear(); + map.put("v_tray_code", trayCodeMakeSure.getTrayCode()); + map.put("v_is_full", trayCodeMakeSure.getIsFull()); + pdaMapper.addInJob(map); + if (!"10".equals(map.get("v_result").toString())) { + return AjaxResult.error(map.get("v_result").toString()); + } + return AjaxResult.success(); + } + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/controller/BasStockController.java b/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/controller/BasStockController.java index e67ac94..0381eb3 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/controller/BasStockController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/controller/BasStockController.java @@ -58,9 +58,10 @@ public class BasStockController extends BaseController */ @PreAuthorize("@ss.hasPermi('stock:management:query')") @GetMapping(value = "/{stockId}") - public AjaxResult getInfo(@PathVariable("stockId") String stockId) + public AjaxResult getInfo(@PathVariable("stockId") String stockId, @RequestParam(value = "warehouseCode", required = false) String warehouseCode) { - return success(basStockService.selectBasStockByStockId(stockId)); + BasStock basStock = basStockService.selectBasStockByStockId2(stockId, warehouseCode); + return success(basStock); } /** @@ -91,9 +92,10 @@ public class BasStockController extends BaseController @PreAuthorize("@ss.hasPermi('stock:management:remove')") @Log(title = "库存信息", businessType = BusinessType.DELETE) @DeleteMapping("/{stockIds}") - public AjaxResult remove(@PathVariable String[] stockIds) + public AjaxResult remove(@PathVariable String[] stockIds,@RequestParam(value = "warehouseCode",required = false) String warehouseCode) { - return toAjax(basStockService.deleteBasStockByStockIds(stockIds)); + System.out.println(warehouseCode); + return toAjax(basStockService.deleteBasStockByStockIds2(stockIds,warehouseCode)); } /** diff --git a/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/domain/BasStock.java b/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/domain/BasStock.java index 10a23e8..98c34c8 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/domain/BasStock.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/domain/BasStock.java @@ -11,6 +11,7 @@ import lombok.ToString; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.springframework.ai.tool.annotation.ToolParam; +import org.springframework.data.annotation.Transient; import java.util.List; @@ -184,6 +185,8 @@ public class BasStock extends BaseEntity /** 仓库 */ // @Excel(name = "${stock.BasStock.warehouseId}") private String warehouseId; + @Transient + private String warehouseCode; /** 垛型ID */ diff --git a/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/mapper/BasStockMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/mapper/BasStockMapper.java index d630f00..4211b88 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/mapper/BasStockMapper.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/mapper/BasStockMapper.java @@ -1,6 +1,7 @@ package com.ruoyi.stock.stock.mapper; import com.ruoyi.in.stockindetail.domain.InStockinDetail; +import com.ruoyi.out.outStockoutDetail.domain.OutStockoutDetail; import com.ruoyi.stock.stock.domain.BasStock; import org.apache.ibatis.annotations.Param; @@ -73,4 +74,20 @@ public interface BasStockMapper List getStockBySerial(String trayCode); List selectHasHalfTray(InStockinDetail inStockinDetail); + + List selectBasStockHcCount(BasStock basStock); + + List selectBasStockListHc(BasStock basStock); + + BasStock selectBasStockByStockId2(String stockId, String warehouseCode); + + int updateBasStock2(BasStock basStock); + + int deleteBasStockByStockIds2(@Param("stockIds") String[] stockIds, @Param("warehouseCode")String warehouseCode); + + List selectBasStockList2(BasStock basStock); + + List selectBasStockHcs(@Param("trayCode") String trayCode, @Param("out") OutStockoutDetail outStockoutDetail); + + BasStock selectBasStockListTopOne(String trayCode); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/service/IBasStockService.java b/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/service/IBasStockService.java index c3ea57b..15b431c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/service/IBasStockService.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/service/IBasStockService.java @@ -83,4 +83,10 @@ public interface IBasStockService AjaxResult resetPdRecord(); List getStockBySerial(String serial); + + BasStock selectBasStockByStockId2(String stockId, String warehouseCode); + + int deleteBasStockByStockIds2(String[] stockIds,String warehouseCode); + + BasStock selectBasStockListTopOne(String trayCode); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/service/impl/BasStockServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/service/impl/BasStockServiceImpl.java index f9ff3f3..fd81cf8 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/service/impl/BasStockServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/stock/stock/service/impl/BasStockServiceImpl.java @@ -58,7 +58,7 @@ public class BasStockServiceImpl implements IBasStockService @Override public List selectBasStockList(BasStock basStock) { - return basStockMapper.selectBasStockList(basStock); + return basStockMapper.selectBasStockList2(basStock); } /** * 无权限查询库存信息列表 @@ -115,10 +115,10 @@ public class BasStockServiceImpl implements IBasStockService @Override public int updateBasStock(BasStock basStock) { - BasStock oldBasStock = basStockMapper.selectBasStockByStockId(basStock.getStockId()); + BasStock oldBasStock = basStockMapper.selectBasStockByStockId2(basStock.getStockId(),basStock.getWarehouseCode()); insertMaintainRecord(oldBasStock,basStock,"2"); insertFreezeRecord(oldBasStock,basStock); - return basStockMapper.updateBasStock(basStock); + return basStockMapper.updateBasStock2(basStock); } private void insertFreezeRecord(BasStock oldBasStock, BasStock basStock) { @@ -194,6 +194,28 @@ public class BasStockServiceImpl implements IBasStockService return basStockMapper.getStockBySerial(trayCode); } + @Override + public BasStock selectBasStockByStockId2(String stockId, String warehouseCode) { + return basStockMapper.selectBasStockByStockId2(stockId,warehouseCode); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteBasStockByStockIds2(String[] stockIds,String warehouseCode) + { + for (String stockId : stockIds) { + BasStock oldBasStock = basStockMapper.selectBasStockByStockId2(stockId,warehouseCode); + insertMaintainRecord(oldBasStock,oldBasStock,"3"); + } + return basStockMapper.deleteBasStockByStockIds2(stockIds,warehouseCode); + } + + @Override + public BasStock selectBasStockListTopOne(String trayCode) { + + return basStockMapper.selectBasStockListTopOne(trayCode); + } + /** * 新增库存信息(不记录维护记录) * diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/license/SysLicenseController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/license/SysLicenseController.java new file mode 100644 index 0000000..536d7c7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/license/SysLicenseController.java @@ -0,0 +1,126 @@ +package com.ruoyi.web.controller.system.license; + +import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +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.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.license.domain.SysLicense; +import com.ruoyi.license.service.ISysLicenseService; +import com.ruoyi.license.util.LicenseUtils; + +/** + * 授权码Controller + * + * @author ruoyi + */ +@RestController +@RequestMapping("/system/license") +public class SysLicenseController extends BaseController +{ + @Autowired + private ISysLicenseService sysLicenseService; + + /** + * 查询授权码列表 + */ + @PreAuthorize("@ss.hasPermi('system:license:list')") + @GetMapping("/list") + public TableDataInfo list(SysLicense sysLicense) + { + startPage(); + List list = sysLicenseService.selectSysLicenseList(sysLicense); + return getDataTable(list); + } + + /** + * 新增授权码 + */ + @PreAuthorize("@ss.hasPermi('system:license:add')") + @Log(title = "授权码", businessType = BusinessType.INSERT) + @PostMapping("/add") + public AjaxResult add(SysLicense sysLicense) + { + return toAjax(sysLicenseService.insertSysLicense(sysLicense)); + } + + /** + * 修改授权码 + */ + @PreAuthorize("@ss.hasPermi('system:license:edit')") + @Log(title = "授权码", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + public AjaxResult edit(SysLicense sysLicense) + { + return toAjax(sysLicenseService.updateSysLicense(sysLicense)); + } + + /** + * 删除授权码 + */ + @PreAuthorize("@ss.hasPermi('system:license:remove')") + @Log(title = "授权码", businessType = BusinessType.DELETE) + @PostMapping("/remove") + public AjaxResult remove(String ids) + { + return toAjax(sysLicenseService.deleteSysLicenseByIds(ids)); + } + + /** + * 激活授权码(无需登录) + */ + @Log(title = "激活授权码", businessType = BusinessType.UPDATE) + @PostMapping("/active") + public AjaxResult active(String licenseCode) + { + if (!LicenseUtils.validateFormat(licenseCode)) + { + return error("授权码格式不正确"); + } + int result = sysLicenseService.activeLicense(licenseCode); + if (result > 0) + { + return success("授权码激活成功"); + } + return error("授权码激活失败,请检查授权码是否正确或已过期"); + } + + /** + * 获取当前授权信息 + * license 未开启或无有效授权时返回 code=200 data=null,前端静默处理 + */ + @GetMapping("/info") + public AjaxResult info() + { + SysLicense license = sysLicenseService.getActiveLicense(); + return AjaxResult.success(license); + } + + /** + * 生成授权码 + */ + @PreAuthorize("@ss.hasPermi('system:license:add')") + @GetMapping("/generate") + public AjaxResult generate(String type, String projectNo) + { + if (StringUtils.isEmpty(type) || StringUtils.isEmpty(projectNo)) + { + return error("授权类型和项目编号不能为空"); + } + String licenseCode = LicenseUtils.generateLicense(type, projectNo); + if (licenseCode == null) + { + return error("授权码生成失败"); + } + return AjaxResult.success("授权码生成成功", licenseCode); + } +} diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml index a75fd22..b328af5 100644 --- a/ruoyi-admin/src/main/resources/application-druid.yml +++ b/ruoyi-admin/src/main/resources/application-druid.yml @@ -6,14 +6,14 @@ spring: druid: # 主库数据源 master: - url: jdbc:sqlserver://172.16.4.141:1433;databaseName=FT546-wms;encrypt=true;trustServerCertificate=true; + url: jdbc:sqlserver://127.0.0.1:1433;databaseName=FT546-wms;encrypt=false; username: sa - password: Flrd0914. + password: 123456 # 从库数据源 slave: # 从数据源开关/默认关闭 enabled: false - url: jdbc:mariadb://172.16.4.141:3307/mydb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + url: jdbc:mariadb://172.16.4.12:3307/mydb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: Flrd0914. # 初始连接数 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 14ccea8..2fa23fb 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -66,12 +66,12 @@ spring: devtools: restart: # 热部署开关 - enabled: true + enabled: false data: # redis 配置 redis: # 地址 - host: 172.16.4.141 + host: 127.0.0.1 # 端口,默认为6379 port: 6379 # 数据库索引 @@ -133,7 +133,12 @@ token: # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) - expireTime: 30 + expireTime: 43800 + +# 授权码配置 +license: + # 首次部署需先执行 sql/sys_license.sql 并激活授权码,再改为 true 启用拦截 + enabled: false @@ -175,4 +180,20 @@ xss: # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* +mybatis-plus: + configuration: + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl +fortucky: + algorithm: + mode: ${FORTUCKY_ALGORITHM_MODE:SHADOW} + warehouse-id: ${FORTUCKY_ALGORITHM_WAREHOUSE_ID:01} + page-size: ${FORTUCKY_ALGORITHM_PAGE_SIZE:100} + database-writes-enabled: ${FORTUCKY_ALGORITHM_DATABASE_WRITES_ENABLED:true} + legacy-fallback-on-technical-error: ${FORTUCKY_ALGORITHM_LEGACY_FALLBACK:false} + tidy-auto-scan-ms: ${FORTUCKY_TIDY_AUTO_SCAN_MS:600000} + tidy-reconcile-ms: ${FORTUCKY_TIDY_RECONCILE_MS:5000} + tidy-claim-lease-seconds: ${FORTUCKY_TIDY_CLAIM_LEASE_SECONDS:60} + tidy-wcs-snapshot-url: ${FORTUCKY_TIDY_WCS_SNAPSHOT_URL:http://localhost:8081/wcs2Wms/api/tidyVehicleSnapshot} + replay-run-id: ${FT546_REPLAY_RUN_ID:} + replay-database: ${FT546_REPLAY_DATABASE:} diff --git a/ruoyi-admin/src/main/resources/mapper/agv/AgvContainerTaskMapper.xml b/ruoyi-admin/src/main/resources/mapper/agv/AgvContainerTaskMapper.xml index 6a067bb..e3198e8 100644 --- a/ruoyi-admin/src/main/resources/mapper/agv/AgvContainerTaskMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/agv/AgvContainerTaskMapper.xml @@ -1,4 +1,4 @@ - + @@ -19,21 +19,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, container, start_point, end_point, create_time, start_time, finish_time, task_no, status, spare1, spare2 from agv_container_task + select top 1 id, container, start_point, end_point, create_time, start_time, finish_time, task_no, status, spare1, spare2 from agv_container_task @@ -101,4 +101,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} + + + delete from agv_container_task where container = #{order} + + + diff --git a/ruoyi-admin/src/main/resources/mapper/ai/ChatMessageMapper.xml b/ruoyi-admin/src/main/resources/mapper/ai/ChatMessageMapper.xml index 99c335a..2ed84a1 100644 --- a/ruoyi-admin/src/main/resources/mapper/ai/ChatMessageMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/ai/ChatMessageMapper.xml @@ -1,4 +1,4 @@ - + @@ -28,14 +28,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -115,3 +115,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" delete from chat_message where conversation_id = #{conversationId} + diff --git a/ruoyi-admin/src/main/resources/mapper/ai/ConversationsMapper.xml b/ruoyi-admin/src/main/resources/mapper/ai/ConversationsMapper.xml index 62ac9b6..2d43b17 100644 --- a/ruoyi-admin/src/main/resources/mapper/ai/ConversationsMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/ai/ConversationsMapper.xml @@ -1,4 +1,4 @@ - + @@ -26,17 +26,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -105,3 +105,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/api/KnowledgeFileMapper.xml b/ruoyi-admin/src/main/resources/mapper/api/KnowledgeFileMapper.xml index 75155ec..a4cc5a1 100644 --- a/ruoyi-admin/src/main/resources/mapper/api/KnowledgeFileMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/api/KnowledgeFileMapper.xml @@ -1,4 +1,4 @@ - + @@ -26,17 +26,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -103,4 +103,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/api/MoveMsgMapper.xml b/ruoyi-admin/src/main/resources/mapper/api/MoveMsgMapper.xml new file mode 100644 index 0000000..7c1519e --- /dev/null +++ b/ruoyi-admin/src/main/resources/mapper/api/MoveMsgMapper.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + select id, tray_code, old_space, new_space, status, send_time, msg, spare1, spare2, spare3, spare4, spare5 from move_msg + + + + + + + + insert into move_msg + + id, + tray_code, + old_space, + new_space, + status, + send_time, + msg, + spare1, + spare2, + spare3, + spare4, + spare5, + + + #{id}, + #{trayCode}, + #{oldSpace}, + #{newSpace}, + #{status}, + #{sendTime}, + #{msg}, + #{spare1}, + #{spare2}, + #{spare3}, + #{spare4}, + #{spare5}, + + + + + update move_msg + + tray_code = #{trayCode}, + old_space = #{oldSpace}, + new_space = #{newSpace}, + status = #{status}, + send_time = #{sendTime}, + msg = #{msg}, + spare1 = #{spare1}, + spare2 = #{spare2}, + spare3 = #{spare3}, + spare4 = #{spare4}, + spare5 = #{spare5}, + + where id = #{id} + + + + delete from move_msg where id = #{id} + + + + delete from move_msg where id in + + #{id} + + + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/AgvPointMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/AgvPointMapper.xml new file mode 100644 index 0000000..cedacf6 --- /dev/null +++ b/ruoyi-admin/src/main/resources/mapper/bas/AgvPointMapper.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + select id, station, type, remark, spare1, spare2, spare3 from agv_point + + + + + + + + insert into agv_point + + id, + station, + type, + remark, + spare1, + spare2, + spare3, + + + #{id}, + #{station}, + #{type}, + #{remark}, + #{spare1}, + #{spare2}, + #{spare3}, + + + + + update agv_point + + station = #{station}, + type = #{type}, + remark = #{remark}, + spare1 = #{spare1}, + spare2 = #{spare2}, + spare3 = #{spare3}, + + where id = #{id} + + + + delete from agv_point where id = #{id} + + + + delete from agv_point where id in + + #{id} + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasContainerDetailsMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasContainerDetailsMapper.xml index 707d37e..914c453 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasContainerDetailsMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasContainerDetailsMapper.xml @@ -1,4 +1,4 @@ - + @@ -23,14 +23,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -90,4 +90,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasContainerMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasContainerMapper.xml index 9fd4d17..12a8819 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasContainerMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasContainerMapper.xml @@ -1,4 +1,4 @@ - + @@ -26,11 +26,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and container_id like concat('%', #{containerId}, '%') - and port_name = #{portName} - and status = #{status} - and product_type_quantity = #{productTypeQuantity} - and update_time = #{updateTime} - and operation_man = #{operationMan} + and port_name like concat('%', #{portName}, '%') + and status like concat('%', #{status}, '%') + and product_type_quantity like concat('%', #{productTypeQuantity}, '%') + and update_time like concat('%', #{updateTime}, '%') + and operation_man like concat('%', #{operationMan}, '%') @@ -102,4 +102,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasCustomerMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasCustomerMapper.xml index d762e50..35e7956 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasCustomerMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasCustomerMapper.xml @@ -1,4 +1,4 @@ - + @@ -39,7 +39,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and customer_group_no like concat('%', #{customerGroupNo}, '%') and customer_name like concat('%', #{customerName}, '%') and simple_name like concat('%', #{simpleName}, '%') - and useable = #{useable} + and useable like concat('%', #{useable}, '%') and business_department like concat('%', #{businessDepartment}, '%') and salesman like concat('%', #{salesman}, '%') and mnemonic_code like concat('%', #{mnemonicCode}, '%') @@ -149,4 +149,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasJobIdMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasJobIdMapper.xml index ba52e38..98985bc 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasJobIdMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasJobIdMapper.xml @@ -1,4 +1,4 @@ - + @@ -34,25 +34,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -162,3 +162,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasLedMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasLedMapper.xml new file mode 100644 index 0000000..eff3bdc --- /dev/null +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasLedMapper.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + select id, + product_id, + spec, + quantity, + send_flag, + ip_address, + tray_code, + model, + product_name, + error_msg + + from bas_led + + + + + + + + + + + + update bas_led + + product_id = #{product_id}, + send_flag = #{sendFlag}, + spec = #{spec}, + quantity = #{quantity}, + + + where id = #{id} + + + + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasProductCodeMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasProductCodeMapper.xml index 5477ce9..fa70aca 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasProductCodeMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasProductCodeMapper.xml @@ -1,4 +1,4 @@ - + @@ -31,7 +31,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -129,4 +129,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasProductPortMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasProductPortMapper.xml index 2fb90aa..690dd4a 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasProductPortMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasProductPortMapper.xml @@ -1,4 +1,4 @@ - + @@ -21,9 +21,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and port_name like concat('%', #{portName}, '%') - and port_type = #{portType} - and port_desc = #{portDesc} - and create_man = #{createMan} + and port_type like concat('%', #{portType}, '%') + and port_desc like concat('%', #{portDesc}, '%') + and create_man like concat('%', #{createMan}, '%') @@ -74,4 +74,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasProductPortRelMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasProductPortRelMapper.xml index ecc6728..53bfd74 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasProductPortRelMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasProductPortRelMapper.xml @@ -1,4 +1,4 @@ - + @@ -43,9 +43,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -63,7 +63,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and product_id not in (select product_id from bas_product_port_rel where port_id=#{portId}) - and product_id = #{productId} + and product_id like concat('%', #{productId}, '%') and product_name like concat('%', #{productName}, '%') @@ -112,3 +112,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasRoadwayMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasRoadwayMapper.xml index 0ca261a..4bb69c0 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasRoadwayMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasRoadwayMapper.xml @@ -1,4 +1,4 @@ - + @@ -23,14 +23,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -90,4 +90,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasSupplierMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasSupplierMapper.xml index b3bbc6b..434e1d9 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasSupplierMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasSupplierMapper.xml @@ -1,4 +1,4 @@ - + @@ -37,7 +37,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and supplier_group_no like concat('%', #{supplierGroupNo}, '%') and supplier_name like concat('%', #{supplierName}, '%') and simple_name like concat('%', #{simpleName}, '%') - and useable = #{useable} + and useable like concat('%', #{useable}, '%') and supplier_arae like concat('%', #{supplierArae}, '%') and taxpayer_registration_number like concat('%', #{taxpayerRegistrationNumber}, '%') and country like concat('%', #{country}, '%') @@ -139,4 +139,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasTagMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasTagMapper.xml index 1d81f5b..4be0cb1 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasTagMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasTagMapper.xml @@ -1,4 +1,4 @@ - + @@ -23,14 +23,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -93,3 +93,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasTraycodeFormatMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasTraycodeFormatMapper.xml index 791a9ff..33caa50 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasTraycodeFormatMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasTraycodeFormatMapper.xml @@ -1,4 +1,4 @@ - + @@ -32,9 +32,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and remarks like concat('%',#{remarks}, '%') and min_num like concat('%',#{minNum}, '%') and max_num like concat('%',#{maxNum}, '%') - and spare1 = #{spare1} - and spare2 = #{spare2} - and spare3 = #{spare3} + and spare1 like concat('%', #{spare1}, '%') + and spare2 like concat('%', #{spare2}, '%') + and spare3 like concat('%', #{spare3}, '%') @@ -103,4 +103,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasTraycodeMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasTraycodeMapper.xml index 631bd54..9adf098 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasTraycodeMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasTraycodeMapper.xml @@ -1,4 +1,4 @@ - + @@ -26,11 +26,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -98,3 +98,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/BasWarehousePortMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/BasWarehousePortMapper.xml index 12d8f18..26b7155 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/BasWarehousePortMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/BasWarehousePortMapper.xml @@ -1,4 +1,4 @@ - + @@ -19,10 +19,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -70,4 +70,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/cargoSpace/BasCargoSpaceMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/cargoSpace/BasCargoSpaceMapper.xml index 0b306a1..ce02176 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/cargoSpace/BasCargoSpaceMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/cargoSpace/BasCargoSpaceMapper.xml @@ -1,4 +1,4 @@ - + @@ -63,24 +63,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and bcs.cargo_space_id like concat('%', #{cargoSpaceId}, '%') - and bcs.warehouse_id = #{warehouseId} - and bcs.roadway_id = #{roadwayId} - and bcs.cargo_area_id = #{cargoAreaId} - and bcs.the_type = #{theType} + and bcs.warehouse_id like concat('%', #{warehouseId}, '%') + and bcs.roadway_id like concat('%', #{roadwayId}, '%') + and bcs.cargo_area_id like concat('%', #{cargoAreaId}, '%') + and bcs.the_type like concat('%', #{theType}, '%') and bcs.the_type_name like concat('%', #{theTypeName}, '%') and bcs.cargo_space_name like concat('%', #{cargoSpaceName}, '%') - and bcs.the_platoon = #{thePlatoon} - and bcs.the_column = #{theColumn} - and bcs.the_floor = #{theFloor} - and bcs.status = #{status} - and bcs.locked = #{locked} + and bcs.the_platoon like concat('%', #{thePlatoon}, '%') + and bcs.the_column like concat('%', #{theColumn}, '%') + and bcs.the_floor like concat('%', #{theFloor}, '%') + and bcs.status like concat('%', #{status}, '%') + and bcs.locked like concat('%', #{locked}, '%') and bcs.tray_code like concat('%', #{trayCode}, '%') - and bcs.cargo_hight = #{cargoHight} - and bcs.iss_double = #{issDouble} - and bcs.group_coding_no = #{groupCodingNo} - and bcs.group_coding = #{groupCoding} - and bcs.cargo_space_logo = #{cargoSpaceLogo} - and bcs.this_cargo_area = #{thisCargoArea} + and bcs.cargo_hight like concat('%', #{cargoHight}, '%') + and bcs.iss_double like concat('%', #{issDouble}, '%') + and bcs.group_coding_no like concat('%', #{groupCodingNo}, '%') + and bcs.group_coding like concat('%', #{groupCoding}, '%') + and bcs.cargo_space_logo like concat('%', #{cargoSpaceLogo}, '%') + and bcs.this_cargo_area like concat('%', #{thisCargoArea}, '%') ${params.warehouseDataScope} @@ -188,10 +188,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" WHERE status = '1' and locked = 'N' - and warehouse_id = #{warehouseId} + and warehouse_id like concat('%', #{warehouseId}, '%') - and roadway_id = #{roadwayId} + and roadway_id like concat('%', #{roadwayId}, '%') ORDER BY the_platoon, the_floor,the_column @@ -202,13 +202,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" bcs.the_platoon, bcs.the_column, bcs.the_floor, - bcs.status, - bs.tray_code, - bs.product_id, - bs.product_name + bcs.status from bas_cargo_space bcs - left join bas_stock bs on bcs.cargo_space_id = bs.cargo_space_id - where bcs.status in ('1', '2') + where bcs.status in ( '2') + diff --git a/ruoyi-admin/src/main/resources/mapper/bas/warehouse/BasWarehouseMapper.xml b/ruoyi-admin/src/main/resources/mapper/bas/warehouse/BasWarehouseMapper.xml index 44029d8..c3bf2f8 100644 --- a/ruoyi-admin/src/main/resources/mapper/bas/warehouse/BasWarehouseMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/bas/warehouse/BasWarehouseMapper.xml @@ -1,4 +1,4 @@ - + @@ -29,11 +29,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and warehouse_name like concat('%', #{warehouseName}, '%') - and address = #{address} - and c_desc = #{cDesc} - and warehouse_kind = #{warehouseKind} - and warehouse_type = #{warehouseType} - and is_current = #{isCurrent} + and address like concat('%', #{address}, '%') + and c_desc like concat('%', #{cDesc}, '%') + and warehouse_kind like concat('%', #{warehouseKind}, '%') + and warehouse_type like concat('%', #{warehouseType}, '%') + and is_current like concat('%', #{isCurrent}, '%') and warehouse_id in @@ -111,3 +111,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/check/CheckCommitRecordMapper.xml b/ruoyi-admin/src/main/resources/mapper/check/CheckCommitRecordMapper.xml index 35ec7e1..86061f3 100644 --- a/ruoyi-admin/src/main/resources/mapper/check/CheckCommitRecordMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/check/CheckCommitRecordMapper.xml @@ -1,4 +1,4 @@ - + @@ -21,13 +21,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -79,4 +79,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{pdGuid} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/check/CheckDifferenceRecordFinishMapper.xml b/ruoyi-admin/src/main/resources/mapper/check/CheckDifferenceRecordFinishMapper.xml index 6aa0b1c..92da99d 100644 --- a/ruoyi-admin/src/main/resources/mapper/check/CheckDifferenceRecordFinishMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/check/CheckDifferenceRecordFinishMapper.xml @@ -1,4 +1,4 @@ - + @@ -72,46 +72,46 @@ - and r.check_stock_detail_id = #{checkStockDetailId} + and r.check_stock_detail_id like concat('%', #{checkStockDetailId}, '%') - and r.stock_id = #{stockId} + and r.stock_id like concat('%', #{stockId}, '%') - and r.tray_code = #{trayCode} + and r.tray_code like concat('%', #{trayCode}, '%') - and r.cargo_space_id = #{cargoSpaceId} + and r.cargo_space_id like concat('%', #{cargoSpaceId}, '%') - and r.product_id = #{productId} + and r.product_id like concat('%', #{productId}, '%') - and r.lot_no = #{lotNo} + and r.lot_no like concat('%', #{lotNo}, '%') - and r.supplier = #{supplier} + and r.supplier like concat('%', #{supplier}, '%') - and r.customer = #{customer} + and r.customer like concat('%', #{customer}, '%') - and r.old_quantity = #{oldQuantity} + and r.old_quantity like concat('%', #{oldQuantity}, '%') - and r.new_quantity = #{newQuantity} + and r.new_quantity like concat('%', #{newQuantity}, '%') - and r.record_type = #{recordType} + and r.record_type like concat('%', #{recordType}, '%') - and r.product_guid = #{productGuid} + and r.product_guid like concat('%', #{productGuid}, '%') - and r.status = #{status} + and r.status like concat('%', #{status}, '%') - and r.warehouse_id = #{warehouseId} + and r.warehouse_id like concat('%', #{warehouseId}, '%') ${params.warehouseDataScope} @@ -200,3 +200,4 @@ + diff --git a/ruoyi-admin/src/main/resources/mapper/check/CheckDifferenceRecordMapper.xml b/ruoyi-admin/src/main/resources/mapper/check/CheckDifferenceRecordMapper.xml index 29b0b26..89d9a8c 100644 --- a/ruoyi-admin/src/main/resources/mapper/check/CheckDifferenceRecordMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/check/CheckDifferenceRecordMapper.xml @@ -1,4 +1,4 @@ - + @@ -72,46 +72,46 @@ - and r.check_stock_detail_id = #{checkStockDetailId} + and r.check_stock_detail_id like concat('%', #{checkStockDetailId}, '%') - and r.stock_id = #{stockId} + and r.stock_id like concat('%', #{stockId}, '%') - and r.tray_code = #{trayCode} + and r.tray_code like concat('%', #{trayCode}, '%') - and r.cargo_space_id = #{cargoSpaceId} + and r.cargo_space_id like concat('%', #{cargoSpaceId}, '%') - and r.product_id = #{productId} + and r.product_id like concat('%', #{productId}, '%') - and r.lot_no = #{lotNo} + and r.lot_no like concat('%', #{lotNo}, '%') - and r.supplier = #{supplier} + and r.supplier like concat('%', #{supplier}, '%') - and r.customer = #{customer} + and r.customer like concat('%', #{customer}, '%') - and r.old_quantity = #{oldQuantity} + and r.old_quantity like concat('%', #{oldQuantity}, '%') - and r.new_quantity = #{newQuantity} + and r.new_quantity like concat('%', #{newQuantity}, '%') - and r.record_type = #{recordType} + and r.record_type like concat('%', #{recordType}, '%') - and r.product_guid = #{productGuid} + and r.product_guid like concat('%', #{productGuid}, '%') - and r.status = #{status} + and r.status like concat('%', #{status}, '%') - and r.warehouse_id = #{warehouseId} + and r.warehouse_id like concat('%', #{warehouseId}, '%') ${params.warehouseDataScope} @@ -200,3 +200,4 @@ + diff --git a/ruoyi-admin/src/main/resources/mapper/check/CheckStockinDetailFinishMapper.xml b/ruoyi-admin/src/main/resources/mapper/check/CheckStockinDetailFinishMapper.xml index 46ecb11..52358bd 100644 --- a/ruoyi-admin/src/main/resources/mapper/check/CheckStockinDetailFinishMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/check/CheckStockinDetailFinishMapper.xml @@ -1,4 +1,4 @@ - + @@ -98,34 +98,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -137,34 +137,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" resultMap="CheckStockinDetailResult"> - and csd.stock_check_guid = #{stockCheckGuid} - and csd.stock_check_id = #{stockCheckId} - and csd.lot_no = #{lotNo} - and csd.product_guid = #{productGuid} - and csd.product_id = #{productId} - and csd.quantity = #{quantity} - and csd.quantity_x = #{quantityX} - and csd.quantity_j = #{quantityJ} - and csd.price = #{price} - and csd.cargo_no = #{cargoNo} - and csd.assign_num = #{assignNum} - and csd.assign_num_x = #{assignNumX} - and csd.assign_num_j = #{assignNumJ} - and csd.print_date = #{printDate} - and csd.stock_status = #{stockStatus} - and csd.supplier_id = #{supplierId} - and csd.customer_id = #{customerId} - and csd.unit = #{unit} - and csd.spec = #{spec} - and csd.scan_num = #{scanNum} - and csd.scan_num_x = #{scanNumX} - and csd.scan_num_j = #{scanNumJ} - and csd.spare1 = #{spare1} - and csd.spare2 = #{spare2} - and csd.spare3 = #{spare3} - and csd.spare4 = #{spare4} - and csd.spare5 = #{spare5} - and csd.spare6 = #{spare6} + and csd.stock_check_guid like concat('%', #{stockCheckGuid}, '%') + and csd.stock_check_id like concat('%', #{stockCheckId}, '%') + and csd.lot_no like concat('%', #{lotNo}, '%') + and csd.product_guid like concat('%', #{productGuid}, '%') + and csd.product_id like concat('%', #{productId}, '%') + and csd.quantity like concat('%', #{quantity}, '%') + and csd.quantity_x like concat('%', #{quantityX}, '%') + and csd.quantity_j like concat('%', #{quantityJ}, '%') + and csd.price like concat('%', #{price}, '%') + and csd.cargo_no like concat('%', #{cargoNo}, '%') + and csd.assign_num like concat('%', #{assignNum}, '%') + and csd.assign_num_x like concat('%', #{assignNumX}, '%') + and csd.assign_num_j like concat('%', #{assignNumJ}, '%') + and csd.print_date like concat('%', #{printDate}, '%') + and csd.stock_status like concat('%', #{stockStatus}, '%') + and csd.supplier_id like concat('%', #{supplierId}, '%') + and csd.customer_id like concat('%', #{customerId}, '%') + and csd.unit like concat('%', #{unit}, '%') + and csd.spec like concat('%', #{spec}, '%') + and csd.scan_num like concat('%', #{scanNum}, '%') + and csd.scan_num_x like concat('%', #{scanNumX}, '%') + and csd.scan_num_j like concat('%', #{scanNumJ}, '%') + and csd.spare1 like concat('%', #{spare1}, '%') + and csd.spare2 like concat('%', #{spare2}, '%') + and csd.spare3 like concat('%', #{spare3}, '%') + and csd.spare4 like concat('%', #{spare4}, '%') + and csd.spare5 like concat('%', #{spare5}, '%') + and csd.spare6 like concat('%', #{spare6}, '%') @@ -283,3 +283,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/check/CheckStockinDetailMapper.xml b/ruoyi-admin/src/main/resources/mapper/check/CheckStockinDetailMapper.xml index 3568f9f..7058fc2 100644 --- a/ruoyi-admin/src/main/resources/mapper/check/CheckStockinDetailMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/check/CheckStockinDetailMapper.xml @@ -1,4 +1,4 @@ - + @@ -63,34 +63,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -235,3 +235,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select * from check_stockin_detail where stock_check_id = #{stockCheckId} + diff --git a/ruoyi-admin/src/main/resources/mapper/check/CheckStockinFinishMapper.xml b/ruoyi-admin/src/main/resources/mapper/check/CheckStockinFinishMapper.xml index c098c28..18c6a9c 100644 --- a/ruoyi-admin/src/main/resources/mapper/check/CheckStockinFinishMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/check/CheckStockinFinishMapper.xml @@ -1,4 +1,4 @@ - + @@ -59,24 +59,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -87,24 +87,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - and cs.stock_check_id = #{stockCheckId} - and cs.check_type = #{checkType} - and cs.create_date = #{createDate} - and cs.create_man_id = #{createManId} - and cs.status = #{status} - and cs.warehouse_id = #{warehouseId} - and cs.finish_date = #{finishDate} - and cs.erp_bill = #{erpBill} - and cs.stock_source = #{stockSource} - and cs.department_no = #{departmentNo} - and cs.customer_no = #{customerNo} - and cs.class_no = #{classNo} - and cs.supplier_no = #{supplierNo} - and cs.spare1 = #{spare1} - and cs.spare2 = #{spare2} - and cs.spare3 = #{spare3} - and cs.spare4 = #{spare4} - and cs.spare5 = #{spare5} + and cs.stock_check_id like concat('%', #{stockCheckId}, '%') + and cs.check_type like concat('%', #{checkType}, '%') + and cs.create_date like concat('%', #{createDate}, '%') + and cs.create_man_id like concat('%', #{createManId}, '%') + and cs.status like concat('%', #{status}, '%') + and cs.warehouse_id like concat('%', #{warehouseId}, '%') + and cs.finish_date like concat('%', #{finishDate}, '%') + and cs.erp_bill like concat('%', #{erpBill}, '%') + and cs.stock_source like concat('%', #{stockSource}, '%') + and cs.department_no like concat('%', #{departmentNo}, '%') + and cs.customer_no like concat('%', #{customerNo}, '%') + and cs.class_no like concat('%', #{classNo}, '%') + and cs.supplier_no like concat('%', #{supplierNo}, '%') + and cs.spare1 like concat('%', #{spare1}, '%') + and cs.spare2 like concat('%', #{spare2}, '%') + and cs.spare3 like concat('%', #{spare3}, '%') + and cs.spare4 like concat('%', #{spare4}, '%') + and cs.spare5 like concat('%', #{spare5}, '%') ${params.warehouseDataScope} @@ -183,3 +183,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/in/InStockinBackMapper.xml b/ruoyi-admin/src/main/resources/mapper/in/InStockinBackMapper.xml index 36519fa..fa0edd4 100644 --- a/ruoyi-admin/src/main/resources/mapper/in/InStockinBackMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/in/InStockinBackMapper.xml @@ -1,4 +1,4 @@ - + @@ -27,38 +27,40 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + select stockin_guid, stockin_id, in_type, create_date, create_man_id, status, warehouse_id, spare5, spare4, spare3, finish_date, spare2, spare1, erp_bill, stock_source, department_no, - customer_no, class_no, supplier_no,send_status,send_time,msg from in_stockin_back + customer_no, class_no, supplier_no,send_status,send_time,msg,company_short_name,account_set_no from in_stockin_back @@ -146,7 +148,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" class_no = #{classNo}, supplier_no = #{supplierNo}, send_status = #{sendStatus}, - send_time = #{senTime}, + send_time = #{sendTime}, msg = #{msg}, where stockin_guid = #{stockinGuid} @@ -165,7 +167,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/in/InStockinDetailBackMapper.xml b/ruoyi-admin/src/main/resources/mapper/in/InStockinDetailBackMapper.xml index 3d14518..797c3c1 100644 --- a/ruoyi-admin/src/main/resources/mapper/in/InStockinDetailBackMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/in/InStockinDetailBackMapper.xml @@ -1,4 +1,4 @@ - + @@ -42,53 +42,95 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + - select stockin_detail_id, stockin_guid, stockin_id, lot_no, product_guid, product_id, quantity, - quantity_x, quantity_j, price, cargo_no, remark, assign_num, assign_num_x, assign_num_j, - print_date, stock_status, supplier_id, customer_id, unit, spec, spare1, spare2, spare3, - spare4, spare5, spare6, scan_num, scan_num_x, scan_num_j, spare7, spare8, spare9, product_name,send_status,send_time,msg from in_stockin_detail_back + select stockin_detail_id, + stockin_guid, + stockin_id, + lot_no, + product_guid, + product_id, + quantity, + quantity_x, + quantity_j, + price, + cargo_no, + remark, + assign_num, + assign_num_x, + assign_num_j, + print_date, + stock_status, + supplier_id, + customer_id, + unit, + spec, + spare1, + spare2, + spare3, + spare4, + spare5, + spare6, + scan_num, + scan_num_x, + scan_num_j, + spare7, + spare8, + spare9, + product_name, + send_status, + send_time, + msg, + source_line_id, + bar_code, + is_batch_manage, + old_project_no + from in_stockin_detail_back @@ -189,7 +231,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update in_stockin_detail_back stockin_guid = #{stockinGuid}, - stockin_id = #{stockinId}, + lot_no = #{lotNo}, product_guid = #{productGuid}, product_id = #{productId}, @@ -222,10 +264,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" spare9 = #{spare9}, product_name = #{productName}, send_status = #{sendStatus}, - send_time = #{senTime}, + send_time = #{sendTime}, msg = #{msg}, - where stockin_detail_id = #{stockinDetailId} + where stockin_id = #{stockinId} @@ -238,4 +280,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{stockinDetailId} - \ No newline at end of file + + + INSERT INTO in_stockin_detail_back_finish + + SELECT * FROM in_stockin_detail_back + WHERE stockin_detail_id = #{item.stockinDetailId} + + + + + DELETE FROM in_stockin_detail_back + WHERE stockin_detail_id IN + + #{item.stockinDetailId} + + + + diff --git a/ruoyi-admin/src/main/resources/mapper/in/InStockinDetailFinishMapper.xml b/ruoyi-admin/src/main/resources/mapper/in/InStockinDetailFinishMapper.xml index 8a9d58d..67aa1e0 100644 --- a/ruoyi-admin/src/main/resources/mapper/in/InStockinDetailFinishMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/in/InStockinDetailFinishMapper.xml @@ -1,4 +1,4 @@ - + @@ -103,34 +103,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -142,34 +142,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" resultMap="InStockinDetailResult"> - and isd.stockin_guid = #{stockinGuid} - and isd.stockin_id = #{stockinId} - and isd.lot_no = #{lotNo} - and isd.product_guid = #{productGuid} - and isd.product_id = #{productId} - and isd.quantity = #{quantity} - and isd.quantity_x = #{quantityX} - and isd.quantity_j = #{quantityJ} - and isd.price = #{price} - and isd.cargo_no = #{cargoNo} - and isd.assign_num = #{assignNum} - and isd.assign_num_x = #{assignNumX} - and isd.assign_num_j = #{assignNumJ} - and isd.print_date = #{printDate} - and isd.stock_status = #{stockStatus} - and isd.supplier_id = #{supplierId} - and isd.customer_id = #{customerId} - and isd.unit = #{unit} - and isd.spec = #{spec} - and isd.spare1 = #{spare1} - and isd.spare2 = #{spare2} - and isd.spare3 = #{spare3} - and isd.spare4 = #{spare4} - and isd.spare5 = #{spare5} - and isd.spare6 = #{spare6} - and isd.scan_num = #{scanNum} - and isd.scan_num_x = #{scanNumX} - and isd.scan_num_j = #{scanNumJ} + and isd.stockin_guid like concat('%', #{stockinGuid}, '%') + and isd.stockin_id like concat('%', #{stockinId}, '%') + and isd.lot_no like concat('%', #{lotNo}, '%') + and isd.product_guid like concat('%', #{productGuid}, '%') + and isd.product_id like concat('%', #{productId}, '%') + and isd.quantity like concat('%', #{quantity}, '%') + and isd.quantity_x like concat('%', #{quantityX}, '%') + and isd.quantity_j like concat('%', #{quantityJ}, '%') + and isd.price like concat('%', #{price}, '%') + and isd.cargo_no like concat('%', #{cargoNo}, '%') + and isd.assign_num like concat('%', #{assignNum}, '%') + and isd.assign_num_x like concat('%', #{assignNumX}, '%') + and isd.assign_num_j like concat('%', #{assignNumJ}, '%') + and isd.print_date like concat('%', #{printDate}, '%') + and isd.stock_status like concat('%', #{stockStatus}, '%') + and isd.supplier_id like concat('%', #{supplierId}, '%') + and isd.customer_id like concat('%', #{customerId}, '%') + and isd.unit like concat('%', #{unit}, '%') + and isd.spec like concat('%', #{spec}, '%') + and isd.spare1 like concat('%', #{spare1}, '%') + and isd.spare2 like concat('%', #{spare2}, '%') + and isd.spare3 like concat('%', #{spare3}, '%') + and isd.spare4 like concat('%', #{spare4}, '%') + and isd.spare5 like concat('%', #{spare5}, '%') + and isd.spare6 like concat('%', #{spare6}, '%') + and isd.scan_num like concat('%', #{scanNum}, '%') + and isd.scan_num_x like concat('%', #{scanNumX}, '%') + and isd.scan_num_j like concat('%', #{scanNumJ}, '%') @@ -288,3 +288,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/in/InStockinDetailMapper.xml b/ruoyi-admin/src/main/resources/mapper/in/InStockinDetailMapper.xml index 4e3ad1a..fd19718 100644 --- a/ruoyi-admin/src/main/resources/mapper/in/InStockinDetailMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/in/InStockinDetailMapper.xml @@ -1,4 +1,4 @@ - + @@ -41,6 +41,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -69,34 +70,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -143,7 +144,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" scan_num_x, scan_num_j, product_name, - + source_line_id, + bar_code, + is_batch_manage, + old_project_no, + #{stockinDetailId}, #{stockinGuid}, @@ -180,7 +185,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{scanNumX}, #{scanNumJ}, #{productName}, - + + #{sourceLineId}, + #{barCode}, + #{isBatchManage}, + #{oldProjectNo}, + + INSERT INTO in_stockin_detail @@ -333,4 +344,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" order by ist.create_date desc + + + + + + + diff --git a/ruoyi-admin/src/main/resources/mapper/in/InStockinFinishMapper.xml b/ruoyi-admin/src/main/resources/mapper/in/InStockinFinishMapper.xml index 5a19b7d..81cad95 100644 --- a/ruoyi-admin/src/main/resources/mapper/in/InStockinFinishMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/in/InStockinFinishMapper.xml @@ -1,4 +1,4 @@ - + @@ -53,7 +53,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select is2.stockin_guid, + select distinct is2.stockin_guid, is2.stockin_id, is2.in_type, is2.create_date, @@ -78,6 +78,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" -- su.user_name from in_stockin_finish is2 left join bas_warehouse bw on is2.warehouse_id = bw.warehouse_id + left join in_stockin_detail is3 on is2.stockin_id=is3.stockin_id -- left join bas_supplier bs on bs.supplier_no = is2.supplier_no -- left join sys_dept sd on is2.department_no = sd.dept_id -- left join sys_user su on su.user_id = is2.create_man_id @@ -86,24 +87,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -121,24 +123,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + diff --git a/ruoyi-admin/src/main/resources/mapper/in/TransferBillCallbackMapper.xml b/ruoyi-admin/src/main/resources/mapper/in/TransferBillCallbackMapper.xml index 8fcd1e0..88eaed5 100644 --- a/ruoyi-admin/src/main/resources/mapper/in/TransferBillCallbackMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/in/TransferBillCallbackMapper.xml @@ -1,4 +1,4 @@ - + @@ -24,14 +24,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -92,4 +92,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/job/MydoJobDetailFinishMapper.xml b/ruoyi-admin/src/main/resources/mapper/job/MydoJobDetailFinishMapper.xml index dd402f1..f32aeea 100644 --- a/ruoyi-admin/src/main/resources/mapper/job/MydoJobDetailFinishMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/job/MydoJobDetailFinishMapper.xml @@ -1,4 +1,4 @@ - + @@ -84,32 +84,32 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from mydo_job_detail_finish mjd left join bas_product bp on mjd.product_id = bp.product_id - and mjd.job_detail_id = #{jobDetailId} - and mjd.job_id = #{jobId} - and mjd.stock_id = #{stockId} - and mjd.lot_no = #{lotNo} - and mjd.in_date = #{inDate} - and mjd.in_or_out_id = #{inOrOutId} - and mjd.in_or_out_d_id = #{inOrOutDId} - and mjd.product_guid = #{productGuid} - and mjd.product_id = #{productId} - and mjd.stock_status = #{stockStatus} - and mjd.in_quantity = #{inQuantity} - and mjd.stock_quantity = #{stockQuantity} - and mjd.out_quantity = #{outQuantity} - and mjd.layer_quantity = #{layerQuantity} - and mjd.out_layer_quantity = #{outLayerQuantity} - and mjd.give_num = #{giveNum} - and mjd.stockin_id = #{stockinId} - and mjd.stacking_id = #{stackingId} - and mjd.exit_id = #{exitId} - and mjd.print_date = #{printDate} - and mjd.customer_id = #{customerId} - and mjd.supplier_id = #{supplierId} - and mjd.spare1 = #{spare1} - and mjd.spare2 = #{spare2} - and mjd.spare3 = #{spare3} - and mjd.spare4 = #{spare4} + and mjd.job_detail_id like concat('%', #{jobDetailId}, '%') + and mjd.job_id like concat('%', #{jobId}, '%') + and mjd.stock_id like concat('%', #{stockId}, '%') + and mjd.lot_no like concat('%', #{lotNo}, '%') + and mjd.in_date like concat('%', #{inDate}, '%') + and mjd.in_or_out_id like concat('%', #{inOrOutId}, '%') + and mjd.in_or_out_d_id like concat('%', #{inOrOutDId}, '%') + and mjd.product_guid like concat('%', #{productGuid}, '%') + and mjd.product_id like concat('%', #{productId}, '%') + and mjd.stock_status like concat('%', #{stockStatus}, '%') + and mjd.in_quantity like concat('%', #{inQuantity}, '%') + and mjd.stock_quantity like concat('%', #{stockQuantity}, '%') + and mjd.out_quantity like concat('%', #{outQuantity}, '%') + and mjd.layer_quantity like concat('%', #{layerQuantity}, '%') + and mjd.out_layer_quantity like concat('%', #{outLayerQuantity}, '%') + and mjd.give_num like concat('%', #{giveNum}, '%') + and mjd.stockin_id like concat('%', #{stockinId}, '%') + and mjd.stacking_id like concat('%', #{stackingId}, '%') + and mjd.exit_id like concat('%', #{exitId}, '%') + and mjd.print_date like concat('%', #{printDate}, '%') + and mjd.customer_id like concat('%', #{customerId}, '%') + and mjd.supplier_id like concat('%', #{supplierId}, '%') + and mjd.spare1 like concat('%', #{spare1}, '%') + and mjd.spare2 like concat('%', #{spare2}, '%') + and mjd.spare3 like concat('%', #{spare3}, '%') + and mjd.spare4 like concat('%', #{spare4}, '%') @@ -299,3 +299,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/job/MydoJobDetailMapper.xml b/ruoyi-admin/src/main/resources/mapper/job/MydoJobDetailMapper.xml index 1222e25..4eac9a1 100644 --- a/ruoyi-admin/src/main/resources/mapper/job/MydoJobDetailMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/job/MydoJobDetailMapper.xml @@ -1,4 +1,4 @@ - + @@ -87,32 +87,32 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from mydo_job_detail mjd left join bas_product bp on mjd.product_id = bp.product_id - and mjd.job_detail_id = #{jobDetailId} - and mjd.job_id = #{jobId} - and mjd.stock_id = #{stockId} - and mjd.lot_no = #{lotNo} - and mjd.in_date = #{inDate} - and mjd.in_or_out_id = #{inOrOutId} - and mjd.in_or_out_d_id = #{inOrOutDId} - and mjd.product_guid = #{productGuid} - and mjd.product_id = #{productId} - and mjd.stock_status = #{stockStatus} - and mjd.in_quantity = #{inQuantity} - and mjd.stock_quantity = #{stockQuantity} - and mjd.out_quantity = #{outQuantity} - and mjd.layer_quantity = #{layerQuantity} - and mjd.out_layer_quantity = #{outLayerQuantity} - and mjd.give_num = #{giveNum} - and mjd.stockin_id = #{stockinId} - and mjd.stacking_id = #{stackingId} - and mjd.exit_id = #{exitId} - and mjd.print_date = #{printDate} - and mjd.customer_id = #{customerId} - and mjd.supplier_id = #{supplierId} - and mjd.spare1 = #{spare1} - and mjd.spare2 = #{spare2} - and mjd.spare3 = #{spare3} - and mjd.spare4 = #{spare4} + and mjd.job_detail_id like concat('%', #{jobDetailId}, '%') + and mjd.job_id like concat('%', #{jobId}, '%') + and mjd.stock_id like concat('%', #{stockId}, '%') + and mjd.lot_no like concat('%', #{lotNo}, '%') + and mjd.in_date like concat('%', #{inDate}, '%') + and mjd.in_or_out_id like concat('%', #{inOrOutId}, '%') + and mjd.in_or_out_d_id like concat('%', #{inOrOutDId}, '%') + and mjd.product_guid like concat('%', #{productGuid}, '%') + and mjd.product_id like concat('%', #{productId}, '%') + and mjd.stock_status like concat('%', #{stockStatus}, '%') + and mjd.in_quantity like concat('%', #{inQuantity}, '%') + and mjd.stock_quantity like concat('%', #{stockQuantity}, '%') + and mjd.out_quantity like concat('%', #{outQuantity}, '%') + and mjd.layer_quantity like concat('%', #{layerQuantity}, '%') + and mjd.out_layer_quantity like concat('%', #{outLayerQuantity}, '%') + and mjd.give_num like concat('%', #{giveNum}, '%') + and mjd.stockin_id like concat('%', #{stockinId}, '%') + and mjd.stacking_id like concat('%', #{stackingId}, '%') + and mjd.exit_id like concat('%', #{exitId}, '%') + and mjd.print_date like concat('%', #{printDate}, '%') + and mjd.customer_id like concat('%', #{customerId}, '%') + and mjd.supplier_id like concat('%', #{supplierId}, '%') + and mjd.spare1 like concat('%', #{spare1}, '%') + and mjd.spare2 like concat('%', #{spare2}, '%') + and mjd.spare3 like concat('%', #{spare3}, '%') + and mjd.spare4 like concat('%', #{spare4}, '%') @@ -403,8 +403,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" mjd.spare3, mjd.spare4, mjd.pick_quantity, - mjd.out_quantity-mjd.pick_quantity as pick_quantity_real, - bp.product_name, + mjd.out_quantity - mjd.pick_quantity as pick_quantity_real, + mjd.product_name, mjd.spare5, mjd.spare6, mjd.spare7, @@ -415,11 +415,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" mj.tray_code from mydo_job_detail mjd - left join bas_product bp on mjd.product_id = bp.product_id + left join mydo_job mj on mjd.job_id = mj.job_id - where mj.exit_id=#{exitId} - and mj.status='3' - and mj.execution_phase=2 + where mj.status = '3' + and mj.execution_phase = 2 + and mj.tray_code = #{trayCode} and mj.in_or_out = #{inOrOut} + diff --git a/ruoyi-admin/src/main/resources/mapper/job/MydoJobFinishMapper.xml b/ruoyi-admin/src/main/resources/mapper/job/MydoJobFinishMapper.xml index f35a52a..2f57631 100644 --- a/ruoyi-admin/src/main/resources/mapper/job/MydoJobFinishMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/job/MydoJobFinishMapper.xml @@ -1,10 +1,10 @@ - + - + @@ -30,6 +30,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + @@ -60,30 +62,30 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select distinct mj.job_id, mj.status, mj.on_line_type, mj.task_no, mj.supplier_id, mj.customer_id, mj.department_id, mj.tray_code, mj.roadway_id, mj.cargo_space_id, mj.target_roadway_id, mj.target_cargo_space_id, mj.line_id, mj.workshop_id, mj.priority, @@ -118,38 +120,40 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" left join bas_cargo_space bcs on mj.cargo_space_id = bcs.cargo_space_id left join bas_cargo_space bcst on mj.target_cargo_space_id = bcst.cargo_space_id left join bas_warehouse bw on mj.warehouse_id = bw.warehouse_id - left join mydo_job_detail mjd on mj.job_id = mjd.job_id + left join mydo_job_detail_finish mjd on mj.job_id = mjd.job_id - and mj.job_id = #{jobId} - and mj.status = #{status} - and mj.on_line_type = #{onLineType} - and mj.task_no = #{taskNo} - and mj.supplier_id = #{supplierId} - and mj.customer_id = #{customerId} - and mj.department_id = #{departmentId} + and mj.job_id like concat('%', #{jobId}, '%') + and mj.status like concat('%', #{status}, '%') + and mj.on_line_type like concat('%', #{onLineType}, '%') + and mj.task_no like concat('%', #{taskNo}, '%') + and mj.supplier_id like concat('%', #{supplierId}, '%') + and mj.customer_id like concat('%', #{customerId}, '%') + and mj.department_id like concat('%', #{departmentId}, '%') and mj.tray_code like concat('%', #{trayCode}, '%') - and mj.roadway_id = #{roadwayId} - and mj.cargo_space_id = #{cargoSpaceId} - and mj.target_roadway_id = #{targetRoadwayId} - and mj.target_cargo_space_id = #{targetCargoSpaceId} + and mj.roadway_id like concat('%', #{roadwayId}, '%') + and mj.cargo_space_id like concat('%', #{cargoSpaceId}, '%') + and mj.target_roadway_id like concat('%', #{targetRoadwayId}, '%') + and mj.target_cargo_space_id like concat('%', #{targetCargoSpaceId}, '%') and mj.line_id like concat('%', #{lineId}, '%') - and mj.workshop_id = #{workshopId} - and mj.priority = #{priority} - and mj.execution_phase = #{executionPhase} - and mj.in_or_out = #{inOrOut} - and mj.create_time >= #{startTime} - and mj.create_time <= #{finishTime} - and mj.entrance_id = #{entranceId} - and mj.exit_id = #{exitId} - and mj.class_id = #{classId} - and mj.warehouse_id = #{warehouseId} - and mj.fault_flag = #{faultFlag} + and mj.workshop_id like concat('%', #{workshopId}, '%') + and mj.priority like concat('%', #{priority}, '%') + and mj.execution_phase like concat('%', #{executionPhase}, '%') + and mj.in_or_out like concat('%', #{inOrOut}, '%') + and mj.start_time >= #{startTime} + and mj.finish_time <= #{finishTime} + and mj.entrance_id like concat('%', #{entranceId}, '%') + and mj.exit_id like concat('%', #{exitId}, '%') + and mj.class_id like concat('%', #{classId}, '%') + and mj.warehouse_id like concat('%', #{warehouseId}, '%') + and mj.fault_flag like concat('%', #{faultFlag}, '%') and mj.in_or_out >=20 and mj.in_or_out not in(28) and mj.in_or_out < 20 and mj.in_or_out not in(5,6) and mj.in_or_out in (5,6) and mj.in_or_out in (28) and mjd.product_id like concat('%', #{productId}, '%') + and mjd.stockin_detail_id like concat('%', #{stockinDetailId}, '%') + order by mj.create_time desc @@ -260,3 +264,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/job/MydoJobMapper.xml b/ruoyi-admin/src/main/resources/mapper/job/MydoJobMapper.xml index fb6af52..0ae080b 100644 --- a/ruoyi-admin/src/main/resources/mapper/job/MydoJobMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/job/MydoJobMapper.xml @@ -1,4 +1,4 @@ - + @@ -75,35 +75,36 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" left join mydo_job_detail mjd on mj.job_id = mjd.job_id - and mj.job_id = #{jobId} - and mj.status = #{status} - and mj.on_line_type = #{onLineType} - and mj.task_no = #{taskNo} - and mj.supplier_id = #{supplierId} - and mj.customer_id = #{customerId} - and mj.department_id = #{departmentId} + and mj.job_id like concat('%', #{jobId}, '%') + and mj.status like concat('%', #{status}, '%') + and mj.on_line_type like concat('%', #{onLineType}, '%') + and mj.task_no like concat('%', #{taskNo}, '%') + and mj.supplier_id like concat('%', #{supplierId}, '%') + and mj.customer_id like concat('%', #{customerId}, '%') + and mj.department_id like concat('%', #{departmentId}, '%') and mj.tray_code like concat('%',#{trayCode},'%') - and mj.roadway_id = #{roadwayId} - and mj.cargo_space_id = #{cargoSpaceId} - and mj.target_roadway_id = #{targetRoadwayId} - and mj.target_cargo_space_id = #{targetCargoSpaceId} + and mj.roadway_id like concat('%', #{roadwayId}, '%') + and mj.cargo_space_id like concat('%', #{cargoSpaceId}, '%') + and mj.target_roadway_id like concat('%', #{targetRoadwayId}, '%') + and mj.target_cargo_space_id like concat('%', #{targetCargoSpaceId}, '%') and mj.line_id like concat('%', #{lineId}, '%') - and mj.workshop_id = #{workshopId} - and mj.priority = #{priority} - and mj.execution_phase = #{executionPhase} - and mj.in_or_out = #{inOrOut} + and mj.workshop_id like concat('%', #{workshopId}, '%') + and mj.priority like concat('%', #{priority}, '%') + and mj.execution_phase like concat('%', #{executionPhase}, '%') + and mj.in_or_out like concat('%', #{inOrOut}, '%') and mj.create_time >= #{startTime} and mj.create_time <= #{finishTime} and mj.entrance_id like concat('%',#{entranceId},'%') and mj.exit_id like concat('%', #{exitId}, '%') - and mj.class_id = #{classId} - and mj.warehouse_id = #{warehouseId} - and mj.fault_flag = #{faultFlag} + and mj.class_id like concat('%', #{classId}, '%') + and mj.warehouse_id like concat('%', #{warehouseId}, '%') + and mj.fault_flag like concat('%', #{faultFlag}, '%') and mj.in_or_out >=20 and mj.in_or_out < 20 and mj.in_or_out in (5,6) and mj.in_or_out in (28) and mjd.product_id like concat('%', #{productId}, '%') + and mjd.stockin_detail_id like concat('%', #{stockinDetailId}, '%') order by mj.create_time desc @@ -205,6 +206,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where job_id = #{jobId} + + + delete from mydo_job where job_id = #{jobId} @@ -237,10 +251,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -260,11 +274,38 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select * from mydo_job where tray_code = #{trayCode} + + + + + + + + + + + + diff --git a/ruoyi-admin/src/main/resources/mapper/out/OutExceptionRecordMapper.xml b/ruoyi-admin/src/main/resources/mapper/out/OutExceptionRecordMapper.xml index 9e432c3..f34c2db 100644 --- a/ruoyi-admin/src/main/resources/mapper/out/OutExceptionRecordMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/out/OutExceptionRecordMapper.xml @@ -1,4 +1,4 @@ - + @@ -22,13 +22,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -83,4 +83,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{outGuid} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/out/OutPickSubmitMapper.xml b/ruoyi-admin/src/main/resources/mapper/out/OutPickSubmitMapper.xml index 37685d6..98b9731 100644 --- a/ruoyi-admin/src/main/resources/mapper/out/OutPickSubmitMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/out/OutPickSubmitMapper.xml @@ -1,4 +1,4 @@ - + @@ -25,16 +25,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -98,4 +98,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/out/OutStockoutBackMapper.xml b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutBackMapper.xml new file mode 100644 index 0000000..0e0f8cd --- /dev/null +++ b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutBackMapper.xml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select stockout_guid, + stockout_id, + out_type, + create_date, + department_no, + customer_no, + create_man_id, + status, + stockout_source, + warehouse_id, + class_now_id, + exit_id, + car_number, + FID, + erp_stockout_id, + start_date, + finish_date, + spare1, + spare2, + spare3, + spare4, + spare5, + spare6, + spare7, + spare8, + send_status, + send_time, + msg, + company_short_name, + account_set_no + from out_stockout_back + + + + + + + + + + insert into out_stockout_back + + stockout_guid, + stockout_id, + out_type, + create_date, + department_no, + customer_no, + create_man_id, + status, + stockout_source, + warehouse_id, + class_now_id, + exit_id, + car_number, + FID, + erp_stockout_id, + start_date, + finish_date, + spare1, + spare2, + spare3, + spare4, + spare5, + spare6, + spare7, + spare8, + send_status, + send_time, + msg, + + + #{stockoutGuid}, + #{stockoutId}, + #{outType}, + #{createDate}, + #{departmentNo}, + #{customerNo}, + #{createManId}, + #{status}, + #{stockoutSource}, + #{warehouseId}, + #{classNowId}, + #{exitId}, + #{carNumber}, + #{FID}, + #{erpStockoutId}, + #{startDate}, + #{finishDate}, + #{spare1}, + #{spare2}, + #{spare3}, + #{spare4}, + #{spare5}, + #{spare6}, + #{spare7}, + #{spare8}, + #{sendStatus}, + #{sendTime}, + #{msg}, + + + + + update out_stockout_back + + stockout_id = #{stockoutId}, + out_type = #{outType}, + create_date = #{createDate}, + department_no = #{departmentNo}, + customer_no = #{customerNo}, + create_man_id = #{createManId}, + status = #{status}, + stockout_source = #{stockoutSource}, + warehouse_id = #{warehouseId}, + class_now_id = #{classNowId}, + exit_id = #{exitId}, + car_number = #{carNumber}, + FID = #{FID}, + erp_stockout_id = #{erpStockoutId}, + start_date = #{startDate}, + finish_date = #{finishDate}, + spare1 = #{spare1}, + spare2 = #{spare2}, + spare3 = #{spare3}, + spare4 = #{spare4}, + spare5 = #{spare5}, + spare6 = #{spare6}, + spare7 = #{spare7}, + spare8 = #{spare8}, + send_status = #{sendStatus}, + send_time = #{sendTime}, + msg = #{msg}, + + where stockout_guid = #{stockoutGuid} + + + + delete from out_stockout_back where stockout_guid = #{stockoutGuid} + + + + delete from out_stockout_back where stockout_guid in + + #{stockoutGuid} + + + diff --git a/ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailBackMapper.xml b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailBackMapper.xml new file mode 100644 index 0000000..0b13b37 --- /dev/null +++ b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailBackMapper.xml @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select stockout_detail_id, + stockout_guid, + stockout_id, + lot_no, + product_guid, + product_id, + quantity, + quantity_x, + quantity_j, + assign_num, + assign_num_x, + assign_num_j, + allot_quantity, + allot_quantity_x, + allot_quantity_j, + price, + remark, + warehouse_id, + out_id, + bukechai_quantity, + kechai_quantity, + entryid, + flat_quantity, + fid, + erp_stockout_id, + unit, + spec, + product_name, + spare1, + spare2, + spare3, + spare4, + spare5, + spare6, + spare7, + spare8, + spare9, + send_status, + send_time, + msg, + source_line_id, + bar_code, + is_batch_manage, + old_project_no + from out_stockout_detail_back + + + + + + + + insert into out_stockout_detail_back + + stockout_detail_id, + stockout_guid, + stockout_id, + lot_no, + product_guid, + product_id, + quantity, + quantity_x, + quantity_j, + assign_num, + assign_num_x, + assign_num_j, + allot_quantity, + allot_quantity_x, + allot_quantity_j, + price, + remark, + warehouse_id, + out_id, + bukechai_quantity, + kechai_quantity, + entryid, + flat_quantity, + fid, + erp_stockout_id, + unit, + spec, + product_name, + spare1, + spare2, + spare3, + spare4, + spare5, + spare6, + spare7, + spare8, + spare9, + send_status, + send_time, + msg, + + + #{stockoutDetailId}, + #{stockoutGuid}, + #{stockoutId}, + #{lotNo}, + #{productGuid}, + #{productId}, + #{quantity}, + #{quantityX}, + #{quantityJ}, + #{assignNum}, + #{assignNumX}, + #{assignNumJ}, + #{allotQuantity}, + #{allotQuantityX}, + #{allotQuantityJ}, + #{price}, + #{remark}, + #{warehouseId}, + #{outId}, + #{bukechaiQuantity}, + #{kechaiQuantity}, + #{entryid}, + #{flatQuantity}, + #{fid}, + #{erpStockoutId}, + #{unit}, + #{spec}, + #{productName}, + #{spare1}, + #{spare2}, + #{spare3}, + #{spare4}, + #{spare5}, + #{spare6}, + #{spare7}, + #{spare8}, + #{spare9}, + #{sendStatus}, + #{sendTime}, + #{msg}, + + + + + update out_stockout_detail_back + + stockout_guid = #{stockoutGuid}, + lot_no = #{lotNo}, + product_guid = #{productGuid}, + product_id = #{productId}, + quantity = #{quantity}, + quantity_x = #{quantityX}, + quantity_j = #{quantityJ}, + assign_num = #{assignNum}, + assign_num_x = #{assignNumX}, + assign_num_j = #{assignNumJ}, + allot_quantity = #{allotQuantity}, + allot_quantity_x = #{allotQuantityX}, + allot_quantity_j = #{allotQuantityJ}, + price = #{price}, + remark = #{remark}, + warehouse_id = #{warehouseId}, + out_id = #{outId}, + bukechai_quantity = #{bukechaiQuantity}, + kechai_quantity = #{kechaiQuantity}, + entryid = #{entryid}, + flat_quantity = #{flatQuantity}, + fid = #{fid}, + erp_stockout_id = #{erpStockoutId}, + unit = #{unit}, + spec = #{spec}, + product_name = #{productName}, + spare1 = #{spare1}, + spare2 = #{spare2}, + spare3 = #{spare3}, + spare4 = #{spare4}, + spare5 = #{spare5}, + spare6 = #{spare6}, + spare7 = #{spare7}, + spare8 = #{spare8}, + spare9 = #{spare9}, + send_status = #{sendStatus}, + send_time = #{sendTime}, + msg = #{msg}, + + where stockout_id = #{stockoutId} + + + + delete + from out_stockout_detail_back + where stockout_detail_id = #{stockoutDetailId} + + + + delete from out_stockout_detail_back where stockout_detail_id in + + #{stockoutDetailId} + + + + + INSERT INTO out_stockout_detail_back_finish + + SELECT * FROM out_stockout_detail_back + WHERE stockout_detail_id = #{item.stockoutDetailId} + + + + + DELETE FROM out_stockout_detail_back + WHERE stockout_detail_id IN + + #{item.stockoutDetailId} + + + + diff --git a/ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailFinishMapper.xml b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailFinishMapper.xml index 0bf97cb..56d4ac2 100644 --- a/ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailFinishMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailFinishMapper.xml @@ -1,4 +1,4 @@ - + @@ -90,36 +90,36 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -253,10 +253,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select d.stockout_detail_id, d.stockout_guid, d.stockout_id, d.lot_no, d.product_guid, d.product_id, d.quantity, d.quantity_x, d.quantity_j, d.assign_num, d.assign_num_x, d.assign_num_j, d.allot_quantity, d.allot_quantity_x, d.allot_quantity_j, d.price, d.remark, d.warehouse_id, d.out_id, d.bukechai_quantity, d.kechai_quantity, d.entryid, d.flat_quantity, d.fid, - d.erp_stockout_id, d.unit, d.spec, d.supplier_id, d.cargo_no, d.create_time, d.print_date, - d.voltage, d.power, d.phase, d.net_weight, d.gross_weight, d.distribution, d.model, d.order_id, - p.product_name + d.erp_stockout_id, d.unit, d.spec, + d.product_name,d.spare1, d.spare2, d.spare3, d.spare4,d.spare5, d.spare6,d.spare7,d.spare8,d.spare9 from out_stockout_detail_finish d left join bas_product p on d.product_id = p.product_id where stockout_guid = #{stockoutGuid} + diff --git a/ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailMapper.xml b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailMapper.xml index 31db6a8..9162384 100644 --- a/ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutDetailMapper.xml @@ -1,4 +1,4 @@ - + @@ -57,42 +57,42 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -141,47 +141,55 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" spare7, spare8, spare9, + source_line_id, + bar_code, + is_batch_manage, + old_project_no, - #{stockoutDetailId}, - #{stockoutGuid}, - #{stockoutId}, - #{lotNo}, - #{productGuid}, - #{productId}, - #{productName}, - #{quantity}, - #{quantityX}, - #{quantityJ}, - #{assignNum}, - #{assignNumX}, - #{assignNumJ}, - #{allotQuantity}, - #{allotQuantityX}, - #{allotQuantityJ}, - #{price}, - #{remark}, - #{warehouseId}, - #{outId}, - #{bukechaiQuantity}, - #{kechaiQuantity}, - #{entryid}, - #{flatQuantity}, - #{fid}, - #{erpStockoutId}, - #{unit}, - #{spec}, - #{spare1}, - #{spare2}, - #{spare3}, - #{spare4}, - #{spare5}, - #{spare6}, - #{spare7}, - #{spare8}, - #{spare9}, - + #{stockoutDetailId}, + #{stockoutGuid}, + #{stockoutId}, + #{lotNo}, + #{productGuid}, + #{productId}, + #{productName}, + #{quantity}, + #{quantityX}, + #{quantityJ}, + #{assignNum}, + #{assignNumX}, + #{assignNumJ}, + #{allotQuantity}, + #{allotQuantityX}, + #{allotQuantityJ}, + #{price}, + #{remark}, + #{warehouseId}, + #{outId}, + #{bukechaiQuantity}, + #{kechaiQuantity}, + #{entryid}, + #{flatQuantity}, + #{fid}, + #{erpStockoutId}, + #{unit}, + #{spec}, + #{spare1}, + #{spare2}, + #{spare3}, + #{spare4}, + #{spare5}, + #{spare6}, + #{spare7}, + #{spare8}, + #{spare9}, + #{sourceLineId}, + #{barCode}, + #{isBatchManage}, + #{oldProjectNo}, + @@ -248,3 +256,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where d.stockout_guid = #{stockoutGuid} + diff --git a/ruoyi-admin/src/main/resources/mapper/out/OutStockoutFinishMapper.xml b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutFinishMapper.xml index b66d614..4168ae0 100644 --- a/ruoyi-admin/src/main/resources/mapper/out/OutStockoutFinishMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutFinishMapper.xml @@ -1,4 +1,4 @@ - + @@ -33,23 +33,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -142,26 +142,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" left join out_stockout_detail_finish d on d.stockout_id = o.stockout_id left join bas_product bp on bp.product_id = d.product_id - and o.stockout_guid = #{stockoutGuid} - and o.stockout_id = #{stockoutId} - and o.out_type = #{outType} - and o.department_no = #{departmentNo} - and o.customer_no = #{customerNo} - and o.create_man_id = #{createManId} - and o.status = #{status} - and o.stockout_source = #{stockoutSource} - and o.warehouse_id = #{warehouseId} - and o.class_now_id = #{classNowId} - and o.exit_id = #{exitId} - and o.car_number = #{carNumber} - and o.FID = #{FID} - and o.erp_stockout_id = #{erpStockoutId} + and o.stockout_guid like concat('%', #{stockoutGuid}, '%') + and o.stockout_id like concat('%', #{stockoutId}, '%') + and o.out_type like concat('%', #{outType}, '%') + and o.department_no like concat('%', #{departmentNo}, '%') + and o.customer_no like concat('%', #{customerNo}, '%') + and o.create_man_id like concat('%', #{createManId}, '%') + and o.status like concat('%', #{status}, '%') + and o.stockout_source like concat('%', #{stockoutSource}, '%') + and o.warehouse_id like concat('%', #{warehouseId}, '%') + and o.class_now_id like concat('%', #{classNowId}, '%') + and o.exit_id like concat('%', #{exitId}, '%') + and o.car_number like concat('%', #{carNumber}, '%') + and o.FID like concat('%', #{FID}, '%') + and o.erp_stockout_id like concat('%', #{erpStockoutId}, '%') and o.create_date >= #{startDate} and o.create_date <= #{finishDate} - and d.product_id = #{productId} + and d.spare4 like concat('%', #{spare4}, '%') + and d.product_id like concat('%', #{productId}, '%') and bp.product_name like concat('%', #{productName}, '%') and bc.customer_name like concat('%', #{customerName}, '%') order by o.create_date desc + diff --git a/ruoyi-admin/src/main/resources/mapper/out/OutStockoutMapper.xml b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutMapper.xml index 84ac0fb..61c9efc 100644 --- a/ruoyi-admin/src/main/resources/mapper/out/OutStockoutMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/out/OutStockoutMapper.xml @@ -1,4 +1,4 @@ - + @@ -29,44 +29,50 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + - select stockout_guid, stockout_id, out_type, create_date, department_no, customer_no, create_man_id, status, stockout_source, warehouse_id, class_now_id, exit_id, car_number, FID, erp_stockout_id,start_date,finish_date,spare1,spare2,spare3,spare4,spare5 from out_stockout + select stockout_guid, stockout_id, out_type, create_date, department_no, customer_no, create_man_id, status, stockout_source, warehouse_id, class_now_id, exit_id, car_number, FID, erp_stockout_id,start_date,finish_date,spare1,spare2,spare3,spare4,spare5,spare6,spare7,spare8 from out_stockout @@ -192,10 +210,43 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{v_stockout_detail_id,mode=IN,jdbcType=VARCHAR}, #{v_stock_id,mode=IN,jdbcType=VARCHAR}, #{v_result,mode=OUT,jdbcType=VARCHAR}, - #{v_resultString,mode=OUT,jdbcType=VARCHAR} + #{v_resultmsg,mode=OUT,jdbcType=VARCHAR} ) } + + + update out_stockout + + stockout_id = #{stockoutId}, + out_type = #{outType}, + create_date = #{createDate}, + department_no = #{departmentNo}, + customer_no = #{customerNo}, + create_man_id = #{createManId}, + status = #{status}, + stockout_source = #{stockoutSource}, + warehouse_id = #{warehouseId}, + class_now_id = #{classNowId}, + exit_id = #{exitId}, + car_number = #{carNumber}, + FID = #{FID}, + erp_stockout_id = #{erpStockoutId}, + start_date = #{startDate}, + finish_date = #{finishDate}, + spare1 = #{spare1}, + spare2 = #{spare2}, + spare4 = #{spare4}, + spare3 = #{spare3}, + spare5 = #{spare5}, + company_short_name = #{companyShortName}, + account_set_no = #{accountSetNo}, + + where stockout_guid = #{stockoutGuid} + + + + + diff --git a/ruoyi-admin/src/main/resources/mapper/out/ViewHandAllotStockMapper.xml b/ruoyi-admin/src/main/resources/mapper/out/ViewHandAllotStockMapper.xml index efa1542..a5fc899 100644 --- a/ruoyi-admin/src/main/resources/mapper/out/ViewHandAllotStockMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/out/ViewHandAllotStockMapper.xml @@ -1,9 +1,9 @@ - + - + @@ -53,58 +53,88 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select stock_id, cargo_space_id, stock_status, product_status, lot_no, in_date, back_date, product_guid, quantity, job_id, tray_code, out_quantity, stockin_detail_id, stockin_id, in_type, in_class_id, warehouse_id, stacking_id, spare1, spare2, spare3, spare4, spare5, spare6, product_id, product_name, voltage, power, phase, net_weight, gross_weight, distribution, model, order_id, spare7, spare8, cargo_space_name, roadway_id, the_platoon, the_column, the_floor, status, locked from view_hand_allot_stock + + select stock_id, cargo_space_id, stock_status, product_status, lot_no, in_date, back_date, product_guid, quantity, job_id, tray_code, out_quantity, stockin_detail_id, stockin_id, in_type, in_class_id, warehouse_id, stacking_id, spare1, spare2, spare3, spare4, spare5, spare6, product_id, product_name, voltage, power, phase, net_weight, gross_weight, distribution, model, order_id, spare7, spare8 from view_hand_allot_stock_hc + - + @@ -256,9 +286,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - delete from view_hand_allot_stock where stock_id in + delete from view_hand_allot_stock where stock_id in #{stockId} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/pda/PdaMapper.xml b/ruoyi-admin/src/main/resources/mapper/pda/PdaMapper.xml index 19d6112..d31df4a 100644 --- a/ruoyi-admin/src/main/resources/mapper/pda/PdaMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/pda/PdaMapper.xml @@ -8,6 +8,7 @@ {call proc_bind_tray_msg( #{v_tray_code,mode=IN,jdbcType=VARCHAR}, #{v_stockin_detail_id,mode=IN,jdbcType=VARCHAR}, + #{v_is_bound_accord,mode=IN,jdbcType=VARCHAR}, #{v_quantity,mode=IN,jdbcType=INTEGER}, #{v_result,mode=OUT,jdbcType=INTEGER}, #{v_resultmsg,mode=OUT,jdbcType=VARCHAR} @@ -17,6 +18,8 @@ {call proc_tp_out( - #{v_exit_id,mode=IN,jdbcType=VARCHAR}, + #{v_tray_type,mode=IN,jdbcType=VARCHAR}, #{v_result,mode=OUT,jdbcType=INTEGER}, #{v_resultmsg,mode=OUT,jdbcType=VARCHAR} )} @@ -142,4 +145,60 @@ #{v_resultmsg,mode=OUT,jdbcType=VARCHAR} )} + + + + + + + + + + + diff --git a/ruoyi-admin/src/main/resources/mapper/pda/TrayMsgMapper.xml b/ruoyi-admin/src/main/resources/mapper/pda/TrayMsgMapper.xml index d56e423..c133e74 100644 --- a/ruoyi-admin/src/main/resources/mapper/pda/TrayMsgMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/pda/TrayMsgMapper.xml @@ -1,4 +1,4 @@ - + @@ -25,9 +25,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" left join bas_product p on d.product_id=p.product_id left join bas_warehouse w on t.warehouse_id=w.warehouse_id - and t.tray_code = #{trayCode} - and t.stockin_detail_id = #{stockinDetailId} - and t.quantity = #{quantity} + and t.tray_code like concat('%', #{trayCode}, '%') + and t.stockin_detail_id like concat('%', #{stockinDetailId}, '%') + and t.quantity like concat('%', #{quantity}, '%') ${params.warehouseDataScope} @@ -78,4 +78,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/productAndStock/ViewProductAndStockMapper.xml b/ruoyi-admin/src/main/resources/mapper/productAndStock/ViewProductAndStockMapper.xml index 8b9d313..d9378e5 100644 --- a/ruoyi-admin/src/main/resources/mapper/productAndStock/ViewProductAndStockMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/productAndStock/ViewProductAndStockMapper.xml @@ -1,4 +1,4 @@ - + @@ -33,22 +33,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -60,24 +60,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" resultMap="ViewProductAndStockResult"> - and only_identity = #{onlyIdentity} - and product_id = #{productId} - and lot_no = #{lotNo} + and only_identity like concat('%', #{onlyIdentity}, '%') + and product_id like concat('%', #{productId}, '%') + and lot_no like concat('%', #{lotNo}, '%') and product_name like concat('%', #{productName}, '%') - and quantity = #{quantity} - and warehouse_id = #{warehouseId} - and stacking_id = #{stackingId} - and spare1 = #{spare1} - and spare2 = #{spare2} - and spare3 = #{spare3} - and spare4 = #{spare4} - and spare5 = #{spare5} - and spare6 = #{spare6} - and voltage = #{voltage} - and power = #{power} - and phase = #{phase} + and quantity like concat('%', #{quantity}, '%') + and warehouse_id like concat('%', #{warehouseId}, '%') + and stacking_id like concat('%', #{stackingId}, '%') + and spare1 like concat('%', #{spare1}, '%') + and spare2 like concat('%', #{spare2}, '%') + and spare3 like concat('%', #{spare3}, '%') + and spare4 like concat('%', #{spare4}, '%') + and spare5 like concat('%', #{spare5}, '%') + and spare6 like concat('%', #{spare6}, '%') + and voltage like concat('%', #{voltage}, '%') + and power like concat('%', #{power}, '%') + and phase like concat('%', #{phase}, '%') @@ -154,3 +154,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/receive/ReceiveStockinDetailFinishMapper.xml b/ruoyi-admin/src/main/resources/mapper/receive/ReceiveStockinDetailFinishMapper.xml index c14cb0a..abbf8c2 100644 --- a/ruoyi-admin/src/main/resources/mapper/receive/ReceiveStockinDetailFinishMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/receive/ReceiveStockinDetailFinishMapper.xml @@ -1,4 +1,4 @@ - + @@ -87,31 +87,31 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -123,31 +123,31 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" resultMap="ReceiveStockinDetailResult"> - and stockin_guid = #{stockinGuid} - and stockin_id = #{stockinId} - and lot_no = #{lotNo} - and product_guid = #{productGuid} - and product_id = #{productId} - and quantity = #{quantity} - and quantity_x = #{quantityX} - and quantity_j = #{quantityJ} - and price = #{price} - and cargo_no = #{cargoNo} - and assign_num = #{assignNum} - and assign_num_x = #{assignNumX} - and assign_num_j = #{assignNumJ} - and print_date = #{printDate} - and stock_status = #{stockStatus} - and supplier_id = #{supplierId} - and customer_id = #{customerId} - and unit = #{unit} - and spec = #{spec} - and spare1 = #{spare1} - and spare2 = #{spare2} - and spare3 = #{spare3} - and spare4 = #{spare4} - and spare5 = #{spare5} - and spare6 = #{spare6} + and stockin_guid like concat('%', #{stockinGuid}, '%') + and stockin_id like concat('%', #{stockinId}, '%') + and lot_no like concat('%', #{lotNo}, '%') + and product_guid like concat('%', #{productGuid}, '%') + and product_id like concat('%', #{productId}, '%') + and quantity like concat('%', #{quantity}, '%') + and quantity_x like concat('%', #{quantityX}, '%') + and quantity_j like concat('%', #{quantityJ}, '%') + and price like concat('%', #{price}, '%') + and cargo_no like concat('%', #{cargoNo}, '%') + and assign_num like concat('%', #{assignNum}, '%') + and assign_num_x like concat('%', #{assignNumX}, '%') + and assign_num_j like concat('%', #{assignNumJ}, '%') + and print_date like concat('%', #{printDate}, '%') + and stock_status like concat('%', #{stockStatus}, '%') + and supplier_id like concat('%', #{supplierId}, '%') + and customer_id like concat('%', #{customerId}, '%') + and unit like concat('%', #{unit}, '%') + and spec like concat('%', #{spec}, '%') + and spare1 like concat('%', #{spare1}, '%') + and spare2 like concat('%', #{spare2}, '%') + and spare3 like concat('%', #{spare3}, '%') + and spare4 like concat('%', #{spare4}, '%') + and spare5 like concat('%', #{spare5}, '%') + and spare6 like concat('%', #{spare6}, '%') @@ -257,3 +257,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/receive/ReceiveStockinDetailMapper.xml b/ruoyi-admin/src/main/resources/mapper/receive/ReceiveStockinDetailMapper.xml index 7dd1219..bfb6770 100644 --- a/ruoyi-admin/src/main/resources/mapper/receive/ReceiveStockinDetailMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/receive/ReceiveStockinDetailMapper.xml @@ -1,4 +1,4 @@ - + @@ -58,31 +58,31 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -202,3 +202,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/receive/ReceiveStockinFinishMapper.xml b/ruoyi-admin/src/main/resources/mapper/receive/ReceiveStockinFinishMapper.xml index 5660555..1f847da 100644 --- a/ruoyi-admin/src/main/resources/mapper/receive/ReceiveStockinFinishMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/receive/ReceiveStockinFinishMapper.xml @@ -1,4 +1,4 @@ - + @@ -86,24 +86,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -114,24 +114,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - and rs.stockin_id = #{stockinId} - and rs.in_type = #{inType} - and rs.create_date = #{createDate} - and rs.create_man_id = #{createManId} - and rs.status = #{status} - and rs.warehouse_id = #{warehouseId} - and rs.spare5 = #{spare5} - and rs.spare4 = #{spare4} - and rs.spare3 = #{spare3} - and rs.finish_date = #{finishDate} - and rs.spare2 = #{spare2} - and rs.spare1 = #{spare1} - and rs.erp_bill = #{erpBill} - and rs.stock_source = #{stockSource} - and rs.department_no = #{departmentNo} - and rs.customer_no = #{customerNo} - and rs.class_no = #{classNo} - and rs.supplier_no = #{supplierNo} + and rs.stockin_id like concat('%', #{stockinId}, '%') + and rs.in_type like concat('%', #{inType}, '%') + and rs.create_date like concat('%', #{createDate}, '%') + and rs.create_man_id like concat('%', #{createManId}, '%') + and rs.status like concat('%', #{status}, '%') + and rs.warehouse_id like concat('%', #{warehouseId}, '%') + and rs.spare5 like concat('%', #{spare5}, '%') + and rs.spare4 like concat('%', #{spare4}, '%') + and rs.spare3 like concat('%', #{spare3}, '%') + and rs.finish_date like concat('%', #{finishDate}, '%') + and rs.spare2 like concat('%', #{spare2}, '%') + and rs.spare1 like concat('%', #{spare1}, '%') + and rs.erp_bill like concat('%', #{erpBill}, '%') + and rs.stock_source like concat('%', #{stockSource}, '%') + and rs.department_no like concat('%', #{departmentNo}, '%') + and rs.customer_no like concat('%', #{customerNo}, '%') + and rs.class_no like concat('%', #{classNo}, '%') + and rs.supplier_no like concat('%', #{supplierNo}, '%') and rs.stockin_id in ( select distinct stockin_id from receive_stockin_detail rsd @@ -195,3 +195,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/requestInterface/RequestLogMapper.xml b/ruoyi-admin/src/main/resources/mapper/requestInterface/RequestLogMapper.xml index 794571f..bae57b6 100644 --- a/ruoyi-admin/src/main/resources/mapper/requestInterface/RequestLogMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/requestInterface/RequestLogMapper.xml @@ -1,4 +1,4 @@ - + @@ -29,20 +29,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -112,10 +112,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" delete from request_log where request_id = #{requestId} + + + + + delete from request_log where request_id in #{requestId} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/search/ViewInJobFlowMapper.xml b/ruoyi-admin/src/main/resources/mapper/search/ViewInJobFlowMapper.xml index 60b2b8d..5ca5fde 100644 --- a/ruoyi-admin/src/main/resources/mapper/search/ViewInJobFlowMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/search/ViewInJobFlowMapper.xml @@ -1,4 +1,4 @@ - + @@ -64,50 +64,50 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and job_id like concat('%', #{jobId}, '%') - and status = #{status} - and on_line_type = #{onLineType} + and status like concat('%', #{status}, '%') + and on_line_type like concat('%', #{onLineType}, '%') and task_no like concat('%', #{taskNo}, '%') - and supplier_id = #{supplierId} - and customer_id = #{customerId} - and department_id = #{departmentId} + and supplier_id like concat('%', #{supplierId}, '%') + and customer_id like concat('%', #{customerId}, '%') + and department_id like concat('%', #{departmentId}, '%') and tray_code like concat('%', #{trayCode}, '%') - and roadway_id = #{roadwayId} - and cargo_space_id = #{cargoSpaceId} - and target_roadway_id = #{targetRoadwayId} - and target_cargo_space_id = #{targetCargoSpaceId} + and roadway_id like concat('%', #{roadwayId}, '%') + and cargo_space_id like concat('%', #{cargoSpaceId}, '%') + and target_roadway_id like concat('%', #{targetRoadwayId}, '%') + and target_cargo_space_id like concat('%', #{targetCargoSpaceId}, '%') and line_id like concat('%', #{lineId}, '%') - and workshop_id = #{workshopId} - and priority = #{priority} - and execution_phase = #{executionPhase} - and in_or_out = #{inOrOut} - and start_time = #{startTime} - and finish_time = #{finishTime} - and entrance_id = #{entranceId} - and exit_id = #{exitId} - and class_id = #{classId} - and warehouse_id = #{warehouseId} - and fault_flag = #{faultFlag} - and job_detail_id = #{jobDetailId} - and stock_id = #{stockId} - and lot_no = #{lotNo} - and in_date = #{inDate} - and in_or_out_id = #{inOrOutId} - and in_or_out_d_id = #{inOrOutDId} - and product_guid = #{productGuid} - and stock_status = #{stockStatus} - and in_quantity = #{inQuantity} - and stock_quantity = #{stockQuantity} - and out_quantity = #{outQuantity} - and stockin_id = #{stockinId} - and stacking_id = #{stackingId} - and spare1 = #{spare1} - and spare2 = #{spare2} - and spare3 = #{spare3} - and stockin_detail_id = #{stockinDetailId} - and spare5 = #{spare5} - and spare6 = #{spare6} - and spec = #{spec} - and unit = #{unit} + and workshop_id like concat('%', #{workshopId}, '%') + and priority like concat('%', #{priority}, '%') + and execution_phase like concat('%', #{executionPhase}, '%') + and in_or_out like concat('%', #{inOrOut}, '%') + and start_time like concat('%', #{startTime}, '%') + and finish_time like concat('%', #{finishTime}, '%') + and entrance_id like concat('%', #{entranceId}, '%') + and exit_id like concat('%', #{exitId}, '%') + and class_id like concat('%', #{classId}, '%') + and warehouse_id like concat('%', #{warehouseId}, '%') + and fault_flag like concat('%', #{faultFlag}, '%') + and job_detail_id like concat('%', #{jobDetailId}, '%') + and stock_id like concat('%', #{stockId}, '%') + and lot_no like concat('%', #{lotNo}, '%') + and in_date like concat('%', #{inDate}, '%') + and in_or_out_id like concat('%', #{inOrOutId}, '%') + and in_or_out_d_id like concat('%', #{inOrOutDId}, '%') + and product_guid like concat('%', #{productGuid}, '%') + and stock_status like concat('%', #{stockStatus}, '%') + and in_quantity like concat('%', #{inQuantity}, '%') + and stock_quantity like concat('%', #{stockQuantity}, '%') + and out_quantity like concat('%', #{outQuantity}, '%') + and stockin_id like concat('%', #{stockinId}, '%') + and stacking_id like concat('%', #{stackingId}, '%') + and spare1 like concat('%', #{spare1}, '%') + and spare2 like concat('%', #{spare2}, '%') + and spare3 like concat('%', #{spare3}, '%') + and stockin_detail_id like concat('%', #{stockinDetailId}, '%') + and spare5 like concat('%', #{spare5}, '%') + and spare6 like concat('%', #{spare6}, '%') + and spec like concat('%', #{spec}, '%') + and unit like concat('%', #{unit}, '%') and product_id like concat('%', #{productId}, '%') and product_name like concat('%', #{productName}, '%') and cargo_space_name like concat('%', #{cargoSpaceName}, '%') @@ -290,4 +290,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{jobId} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/search/ViewOutJobFlowMapper.xml b/ruoyi-admin/src/main/resources/mapper/search/ViewOutJobFlowMapper.xml index 69d3e3a..2522f3e 100644 --- a/ruoyi-admin/src/main/resources/mapper/search/ViewOutJobFlowMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/search/ViewOutJobFlowMapper.xml @@ -1,4 +1,4 @@ - + @@ -64,50 +64,50 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and job_id like concat('%', #{jobId}, '%') - and status = #{status} - and on_line_type = #{onLineType} + and status like concat('%', #{status}, '%') + and on_line_type like concat('%', #{onLineType}, '%') and task_no like concat('%', #{taskNo}, '%') - and supplier_id = #{supplierId} - and customer_id = #{customerId} - and department_id = #{departmentId} + and supplier_id like concat('%', #{supplierId}, '%') + and customer_id like concat('%', #{customerId}, '%') + and department_id like concat('%', #{departmentId}, '%') and tray_code like concat('%', #{trayCode}, '%') - and roadway_id = #{roadwayId} - and cargo_space_id = #{cargoSpaceId} - and target_roadway_id = #{targetRoadwayId} - and target_cargo_space_id = #{targetCargoSpaceId} + and roadway_id like concat('%', #{roadwayId}, '%') + and cargo_space_id like concat('%', #{cargoSpaceId}, '%') + and target_roadway_id like concat('%', #{targetRoadwayId}, '%') + and target_cargo_space_id like concat('%', #{targetCargoSpaceId}, '%') and line_id like concat('%', #{lineId}, '%') - and workshop_id = #{workshopId} - and priority = #{priority} - and execution_phase = #{executionPhase} - and in_or_out = #{inOrOut} - and start_time = #{startTime} - and finish_time = #{finishTime} - and entrance_id = #{entranceId} - and exit_id = #{exitId} - and class_id = #{classId} - and warehouse_id = #{warehouseId} - and fault_flag = #{faultFlag} - and job_detail_id = #{jobDetailId} - and stock_id = #{stockId} - and lot_no = #{lotNo} - and in_date = #{inDate} - and in_or_out_id = #{inOrOutId} - and in_or_out_d_id = #{inOrOutDId} - and product_guid = #{productGuid} - and stock_status = #{stockStatus} - and in_quantity = #{inQuantity} - and stock_quantity = #{stockQuantity} - and out_quantity = #{outQuantity} - and stockin_id = #{stockinId} - and stacking_id = #{stackingId} - and spare1 = #{spare1} - and spare2 = #{spare2} - and spare3 = #{spare3} - and stockin_detail_id = #{stockinDetailId} + and workshop_id like concat('%', #{workshopId}, '%') + and priority like concat('%', #{priority}, '%') + and execution_phase like concat('%', #{executionPhase}, '%') + and in_or_out like concat('%', #{inOrOut}, '%') + and start_time like concat('%', #{startTime}, '%') + and finish_time like concat('%', #{finishTime}, '%') + and entrance_id like concat('%', #{entranceId}, '%') + and exit_id like concat('%', #{exitId}, '%') + and class_id like concat('%', #{classId}, '%') + and warehouse_id like concat('%', #{warehouseId}, '%') + and fault_flag like concat('%', #{faultFlag}, '%') + and job_detail_id like concat('%', #{jobDetailId}, '%') + and stock_id like concat('%', #{stockId}, '%') + and lot_no like concat('%', #{lotNo}, '%') + and in_date like concat('%', #{inDate}, '%') + and in_or_out_id like concat('%', #{inOrOutId}, '%') + and in_or_out_d_id like concat('%', #{inOrOutDId}, '%') + and product_guid like concat('%', #{productGuid}, '%') + and stock_status like concat('%', #{stockStatus}, '%') + and in_quantity like concat('%', #{inQuantity}, '%') + and stock_quantity like concat('%', #{stockQuantity}, '%') + and out_quantity like concat('%', #{outQuantity}, '%') + and stockin_id like concat('%', #{stockinId}, '%') + and stacking_id like concat('%', #{stackingId}, '%') + and spare1 like concat('%', #{spare1}, '%') + and spare2 like concat('%', #{spare2}, '%') + and spare3 like concat('%', #{spare3}, '%') + and stockin_detail_id like concat('%', #{stockinDetailId}, '%') and spare5 like concat('%', #{spare5}, '%') - and spare6 = #{spare6} - and spec = #{spec} - and unit = #{unit} + and spare6 like concat('%', #{spare6}, '%') + and spec like concat('%', #{spec}, '%') + and unit like concat('%', #{unit}, '%') and product_id like concat('%', #{productId}, '%') and product_name like concat('%', #{productName}, '%') and cargo_space_name like concat('%', #{cargoSpaceName}, '%') @@ -290,4 +290,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{jobId} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/search/ViewStockDetailMapper.xml b/ruoyi-admin/src/main/resources/mapper/search/ViewStockDetailMapper.xml index 6881df7..ecb5e5d 100644 --- a/ruoyi-admin/src/main/resources/mapper/search/ViewStockDetailMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/search/ViewStockDetailMapper.xml @@ -1,4 +1,4 @@ - + @@ -54,46 +54,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -246,4 +246,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{onlyIdentity} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/search/ViewStockSecureMapper.xml b/ruoyi-admin/src/main/resources/mapper/search/ViewStockSecureMapper.xml index 3c958a5..2cc2774 100644 --- a/ruoyi-admin/src/main/resources/mapper/search/ViewStockSecureMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/search/ViewStockSecureMapper.xml @@ -1,4 +1,4 @@ - + @@ -103,8 +103,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and stock_id like concat('%', #{stockId}, '%') and cargo_space_id like concat('%', #{cargoSpaceId}, '%') - and stock_status = #{stockStatus} - and product_status = #{productStatus} + and stock_status like concat('%', #{stockStatus}, '%') + and product_status like concat('%', #{productStatus}, '%') and lot_no like concat('%', #{lotNo}, '%') and in_date like concat('%', #{inDate}, '%') and back_date like concat('%', #{backDate}, '%') @@ -114,7 +114,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and out_quantity like concat('%', #{outQuantity}, '%') and stockin_detail_id like concat('%', #{stockinDetailId}, '%') and stockin_id like concat('%', #{stockinId}, '%') - and in_type = #{inType} + and in_type like concat('%', #{inType}, '%') and in_class_id like concat('%', #{inClassId}, '%') and warehouse_id like concat('%', #{warehouseId}, '%') and stacking_id like concat('%', #{stackingId}, '%') @@ -123,7 +123,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and c_desc like concat('%', #{cDesc}, '%') and warehouse_kind like concat('%', #{warehouseKind}, '%') and warehouse_type like concat('%', #{warehouseType}, '%') - and is_current = #{isCurrent} + and is_current like concat('%', #{isCurrent}, '%') and product_guid like concat('%', #{productGuid}, '%') and product_id like concat('%', #{productId}, '%') and parent_id like concat('%', #{parentId}, '%') @@ -180,8 +180,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and the_platoon like concat('%', #{thePlatoon}, '%') and the_column like concat('%', #{theColumn}, '%') and the_floor like concat('%', #{theFloor}, '%') - and cargo_status = #{cargoStatus} - and locked = #{locked} + and cargo_status like concat('%', #{cargoStatus}, '%') + and locked like concat('%', #{locked}, '%') and cargo_hight like concat('%', #{cargoHight}, '%') and iss_double like concat('%', #{issDouble}, '%') and group_coding_no like concat('%', #{groupCodingNo}, '%') @@ -481,4 +481,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{stockId} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/search/ViewStockWarningMapper.xml b/ruoyi-admin/src/main/resources/mapper/search/ViewStockWarningMapper.xml index abea5e6..a5d82bd 100644 --- a/ruoyi-admin/src/main/resources/mapper/search/ViewStockWarningMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/search/ViewStockWarningMapper.xml @@ -1,4 +1,4 @@ - + @@ -103,8 +103,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and stock_id like concat('%', #{stockId}, '%') and cargo_space_id like concat('%', #{cargoSpaceId}, '%') - and stock_status = #{stockStatus} - and product_status = #{productStatus} + and stock_status like concat('%', #{stockStatus}, '%') + and product_status like concat('%', #{productStatus}, '%') and lot_no like concat('%', #{lotNo}, '%') and in_date like concat('%', #{inDate}, '%') and back_date like concat('%', #{backDate}, '%') @@ -114,7 +114,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and out_quantity like concat('%', #{outQuantity}, '%') and stockin_detail_id like concat('%', #{stockinDetailId}, '%') and stockin_id like concat('%', #{stockinId}, '%') - and in_type = #{inType} + and in_type like concat('%', #{inType}, '%') and in_class_id like concat('%', #{inClassId}, '%') and warehouse_id like concat('%', #{warehouseId}, '%') and stacking_id like concat('%', #{stackingId}, '%') @@ -180,8 +180,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and the_platoon like concat('%', #{thePlatoon}, '%') and the_column like concat('%', #{theColumn}, '%') and the_floor like concat('%', #{theFloor}, '%') - and cargo_status = #{cargoStatus} - and locked = #{locked} + and cargo_status like concat('%', #{cargoStatus}, '%') + and locked like concat('%', #{locked}, '%') and cargo_hight like concat('%', #{cargoHight}, '%') and iss_double like concat('%', #{issDouble}, '%') and group_coding_no like concat('%', #{groupCodingNo}, '%') @@ -481,4 +481,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{stockId} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/search/ViewStockinHistoryMapper.xml b/ruoyi-admin/src/main/resources/mapper/search/ViewStockinHistoryMapper.xml index ee6b8ca..87fdbf3 100644 --- a/ruoyi-admin/src/main/resources/mapper/search/ViewStockinHistoryMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/search/ViewStockinHistoryMapper.xml @@ -1,4 +1,4 @@ - + @@ -53,43 +53,43 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -240,4 +240,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{stockinGuid} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/search/ViewStockoutHistoryMapper.xml b/ruoyi-admin/src/main/resources/mapper/search/ViewStockoutHistoryMapper.xml index ba2e846..a200e57 100644 --- a/ruoyi-admin/src/main/resources/mapper/search/ViewStockoutHistoryMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/search/ViewStockoutHistoryMapper.xml @@ -1,4 +1,4 @@ - + @@ -45,36 +45,36 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -200,4 +200,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{stockoutGuid} - \ No newline at end of file + diff --git a/ruoyi-admin/src/main/resources/mapper/stock/BasStockFreezeRecordMapper.xml b/ruoyi-admin/src/main/resources/mapper/stock/BasStockFreezeRecordMapper.xml index 33487a0..ac95dfb 100644 --- a/ruoyi-admin/src/main/resources/mapper/stock/BasStockFreezeRecordMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/stock/BasStockFreezeRecordMapper.xml @@ -1,4 +1,4 @@ - + @@ -37,22 +37,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - and stock_id = #{stockId} - and bsmr.cargo_space_id = #{cargoSpaceId} - and bsmr.tray_code = #{trayCode} - and product_id = #{productId} + and stock_id like concat('%', #{stockId}, '%') + and bsmr.cargo_space_id like concat('%', #{cargoSpaceId}, '%') + and bsmr.tray_code like concat('%', #{trayCode}, '%') + and product_id like concat('%', #{productId}, '%') and product_name like concat('%', #{productName}, '%') - and print_date = #{printDate} - and lot_no = #{lotNo} - and old_quantity = #{oldQuantity} - and quantity = #{quantity} - and method = #{method} - and bsmr.warehouse_id = #{warehouseId} - and stock_detail_id = #{stockDetailId} - and operating_target = #{operatingTarget} - and bar_code_old_quantity = #{barCodeOldQuantity} - and bar_code_quantity = #{barCodeQuantity} - and product_guid = #{productGuid} + and print_date like concat('%', #{printDate}, '%') + and lot_no like concat('%', #{lotNo}, '%') + and old_quantity like concat('%', #{oldQuantity}, '%') + and quantity like concat('%', #{quantity}, '%') + and method like concat('%', #{method}, '%') + and bsmr.warehouse_id like concat('%', #{warehouseId}, '%') + and stock_detail_id like concat('%', #{stockDetailId}, '%') + and operating_target like concat('%', #{operatingTarget}, '%') + and bar_code_old_quantity like concat('%', #{barCodeOldQuantity}, '%') + and bar_code_quantity like concat('%', #{barCodeQuantity}, '%') + and product_guid like concat('%', #{productGuid}, '%') ${params.warehouseDataScope} @@ -144,3 +144,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + diff --git a/ruoyi-admin/src/main/resources/mapper/stock/BasStockMapper.xml b/ruoyi-admin/src/main/resources/mapper/stock/BasStockMapper.xml index b24b53c..ffa78de 100644 --- a/ruoyi-admin/src/main/resources/mapper/stock/BasStockMapper.xml +++ b/ruoyi-admin/src/main/resources/mapper/stock/BasStockMapper.xml @@ -1,123 +1,283 @@ - + + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - select bs.stock_id, bs.cargo_space_id, bs.stock_status, bs.product_status, bs.lot_no, bs.in_date, - bs.back_date, bs.product_guid, bs.quantity, bs.job_id, bs.tray_code, bs.out_quantity, - bs.stockin_detail_id, bs.stockin_id, bs.in_type, bs.in_class_id, bs.warehouse_id, bs.stacking_id, - bs.spare1, bs.spare2, bs.spare3, bs.spare4, bs.spare5, bs.spare6 , - bs.voltage,bs.power,bs.phase,bs.net_weight,bs.gross_weight,bs.distribution,bs.model,bs.order_id, - bs.product_name,bp.spare1 as englishDesc, - bp.spare2 as netWeight,bp.spare5 as length,bp.spare6 as width,bp.spare7 as height,bp.spare8 as volume,bw.warehouse_name,bs.product_id, - bcs.locked,bcs.cargo_space_name,bcs.status as cargoSpaceStockStatus + select bs.stock_id, + bs.cargo_space_id, + bs.stock_status, + bs.product_status, + bs.lot_no, + bs.in_date, + bs.back_date, + bs.product_guid, + bs.quantity, + bs.job_id, + bs.tray_code, + bs.out_quantity, + bs.stockin_detail_id, + bs.stockin_id, + bs.in_type, + bs.in_class_id, + bs.warehouse_id, + bs.stacking_id, + bs.spare1, + bs.spare2, + bs.spare3, + bs.spare4, + bs.spare5, + bs.spare6, + bs.voltage, + bs.power, + bs.phase, + bs.net_weight, + bs.gross_weight, + bs.distribution, + bs.model, + bs.order_id, + bs.product_name, + bp.spare1 as englishDesc, + bp.spare2 as netWeight, + bp.spare5 as length, + bp.spare6 as width, + bp.spare7 as height, + bp.spare8 as volume, + bw.warehouse_name, + bs.product_id, + bcs.locked, + bcs.cargo_space_name, + bcs.status as cargoSpaceStockStatus from bas_stock bs - left join bas_product bp on bs.product_id = bp.product_id - left join bas_warehouse bw on bs.warehouse_id = bw.warehouse_id - left join bas_cargo_space bcs on bs.cargo_space_id = bcs.cargo_space_id + left join bas_product bp on bs.product_id = bp.product_id + left join bas_warehouse bw on bs.warehouse_id = bw.warehouse_id + left join bas_cargo_space bcs on bs.cargo_space_id = bcs.cargo_space_id + + + + + + + insert into bas_stock @@ -146,7 +306,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" spare5, spare6, product_id, - + #{stockId}, #{cargoSpaceId}, @@ -173,18 +333,62 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{spare5}, #{spare6}, #{productId}, - + INSERT INTO bas_stock - (stock_id,cargo_space_id,stock_status,product_status,lot_no,in_date,back_date,product_guid,quantity,job_id,tray_code,out_quantity,stockin_detail_id,stockin_id,in_type,in_class_id,warehouse_id,stacking_id,spare1,spare2,spare3,spare4,spare5,spare6,product_id,product_name,voltage,power,phase,net_weight,gross_weight,distribution,model,order_id,spare7) + (stock_id,cargo_space_id,stock_status,product_status,lot_no,in_date,back_date,product_guid,quantity,job_id,tray_code,out_quantity,stockin_detail_id,stockin_id,in_type,in_class_id,warehouse_id,stacking_id,spare1,spare2,spare3,spare4,spare5,spare6,product_id,product_name,voltage,power,phase,net_weight,gross_weight,distribution,model,order_id,spare7) VALUES - - (#{item.stockId},#{item.cargoSpaceId},#{item.stockStatus},#{item.productStatus},#{item.lotNo},#{item.inDate},#{item.backDate},#{item.productGuid},#{item.quantity},#{item.jobId},#{item.trayCode},#{item.outQuantity},#{item.stockinDetailId},#{item.stockinId},#{item.inType},#{item.inClassId},#{item.warehouseId},#{item.stackingId},#{item.spare1},#{item.spare2},#{item.spare3},#{item.spare4},#{item.spare5},#{item.spare6},#{item.productId} - ,#{item.productName},#{item.voltage},#{item.power},#{item.phase},#{item.netWeight},#{item.grossWeight},#{item.distribution},#{item.model},#{item.orderId},#{item.spare7}) - + + (#{item.stockId},#{item.cargoSpaceId},#{item.stockStatus},#{item.productStatus},#{item.lotNo},#{item.inDate},#{item.backDate},#{item.productGuid},#{item.quantity},#{item.jobId},#{item.trayCode},#{item.outQuantity},#{item.stockinDetailId},#{item.stockinId},#{item.inType},#{item.inClassId},#{item.warehouseId},#{item.stackingId},#{item.spare1},#{item.spare2},#{item.spare3},#{item.spare4},#{item.spare5},#{item.spare6},#{item.productId} + ,#{item.productName},#{item.voltage},#{item.power},#{item.phase},#{item.netWeight},#{item.grossWeight},#{item.distribution},#{item.model},#{item.orderId},#{item.spare7}) + + + + + update bas_stock + + + update bas_stock_hc + + + update bas_stock + + + + + cargo_space_id = #{cargoSpaceId}, + stock_status = #{stockStatus}, + product_status = #{productStatus}, + lot_no = #{lotNo}, + in_date = #{inDate}, + back_date = #{backDate}, + product_guid = #{productGuid}, + quantity = #{quantity}, + job_id = #{jobId}, + tray_code = #{trayCode}, + out_quantity = #{outQuantity}, + stockin_detail_id = #{stockinDetailId}, + stockin_id = #{stockinId}, + in_type = #{inType}, + in_class_id = #{inClassId}, + warehouse_id = #{warehouseId}, + stacking_id = #{stackingId}, + spare1 = #{spare1}, + spare2 = #{spare2}, + spare3 = #{spare3}, + spare4 = #{spare4}, + spare5 = #{spare5}, + spare6 = #{spare6}, + product_id = #{productId}, + + + WHERE stock_id = #{stockId} + + + update bas_stock @@ -216,14 +420,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where stock_id = #{stockId} - update bas_stock set stock_status = #{stockStatus} where tray_code = #{trayCode} + update bas_stock + set stock_status = #{stockStatus} + where tray_code = #{trayCode} - update bas_stock set spare7 = '0' + update bas_stock + set spare7 = '0' - delete from bas_stock where stock_id = #{stockId} + delete + from bas_stock + where stock_id = #{stockId} @@ -233,11 +442,30 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + delete from bas_stock where stock_id in + + + delete from bas_stock_hc where stock_id in + + + delete from bas_stock where stock_id in + + + + #{stockId} + + + + + + + + + + + + + + + select bs.stock_id, + bs.cargo_space_id, + bs.stock_status, + bs.product_status, + bs.lot_no, + bs.in_date, + bs.back_date, + bs.product_guid, + bs.quantity, + bs.job_id, + bs.tray_code, + bs.out_quantity, + bs.stockin_detail_id, + bs.stockin_id, + bs.in_type, + bs.in_class_id, + bs.warehouse_id, + bs.stacking_id, + bs.spare1, + bs.spare2, + bs.spare3, + bs.spare4, + bs.spare5, + bs.spare6, + bs.voltage, + bs.power, + bs.phase, + bs.net_weight, + bs.gross_weight, + bs.distribution, + bs.model, + bs.order_id, + bs.product_name, + bs.product_id + from bas_stock_hc bs + + + diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/AlgorithmShadowConfigurationTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/AlgorithmShadowConfigurationTest.java new file mode 100644 index 0000000..90ee9ca --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/AlgorithmShadowConfigurationTest.java @@ -0,0 +1,25 @@ +package com.ruoyi.algorithm.wms; + +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; + +class AlgorithmShadowConfigurationTest { + @Test + void applicationDefaultsAlgorithmToShadowWithExplicitSafeOverrides() throws IOException { + try (var stream = getClass().getClassLoader().getResourceAsStream("application.yml")) { + if (stream == null) { + throw new IOException("Missing application.yml"); + } + String configuration = new String(stream.readAllBytes(), StandardCharsets.UTF_8); + assertThat(configuration).contains( + "mode: ${FORTUCKY_ALGORITHM_MODE:SHADOW}", + "warehouse-id: ${FORTUCKY_ALGORITHM_WAREHOUSE_ID:01}", + "database-writes-enabled: ${FORTUCKY_ALGORITHM_DATABASE_WRITES_ENABLED:true}", + "legacy-fallback-on-technical-error: ${FORTUCKY_ALGORITHM_LEGACY_FALLBACK:false}"); + } + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/InboundAllocationTransactionTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/InboundAllocationTransactionTest.java new file mode 100644 index 0000000..4133178 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/InboundAllocationTransactionTest.java @@ -0,0 +1,114 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.algorithm.inbound.InboundAssignment; +import com.ruoyi.algorithm.inbound.InboundBorrowType; +import com.ruoyi.algorithm.inbound.InboundLadderRung; +import com.ruoyi.algorithm.inbound.InboundPlan; +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.repository.ReservationResult; +import com.ruoyi.algorithm.repository.VersionToken; +import com.ruoyi.algorithm.service.InboundPlanningResult; +import com.ruoyi.algorithm.service.InboundReservationOutcome; +import com.ruoyi.job.mydojob.domain.MydoJob; +import com.ruoyi.job.mydojob.mapper.MydoJobMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.dao.CannotAcquireLockException; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class InboundAllocationTransactionTest { + private SchedulingFacade facade; + private WmsAlgorithmMapper algorithmMapper; + private MydoJobMapper jobMapper; + private InboundAllocationTransaction transaction; + private MydoJob job; + + @BeforeEach + void setUp() { + facade = mock(SchedulingFacade.class); + algorithmMapper = mock(WmsAlgorithmMapper.class); + jobMapper = mock(MydoJobMapper.class); + transaction = new InboundAllocationTransaction(facade, algorithmMapper, jobMapper); + job = new MydoJob(); + job.setJobId("J-1"); + job.setTaskNo("T-1"); + job.setWarehouseId("01"); + job.setCargoSpaceId("OLD-SPACE"); + job.setTrayCode("TRAY-1"); + } + + @Test + void releasesOnlyTheJobsOwnUnstockedPreallocation() { + when(algorithmMapper.releaseInboundSpace("J-1", "01", "OLD-SPACE", "TRAY-1")) + .thenReturn(1); + when(algorithmMapper.clearInboundJobAssignment("J-1", "OLD-SPACE")).thenReturn(1); + MydoJob cleared = new MydoJob(); + cleared.setJobId("J-1"); + when(jobMapper.selectInJobByTaskNo("T-1")).thenReturn(cleared); + + MydoJob result = transaction.release(job); + + assertThat(result).isSameAs(cleared); + verify(algorithmMapper).clearInboundJobAssignment("J-1", "OLD-SPACE"); + } + + @Test + void refusesToClearTheJobWhenTheOldSpaceIsNoLongerReleasable() { + when(algorithmMapper.releaseInboundSpace("J-1", "01", "OLD-SPACE", "TRAY-1")) + .thenReturn(0); + + assertThatThrownBy(() -> transaction.release(job)) + .isInstanceOf(CannotAcquireLockException.class); + verify(algorithmMapper, never()).clearInboundJobAssignment("J-1", "OLD-SPACE"); + } + + @Test + void exposesOneTransactionalReserveAndCommitBoundary() { + var method = Arrays.stream(InboundAllocationTransaction.class.getDeclaredMethods()) + .filter(candidate -> candidate.getName().equals("reserveAndCommit")) + .findFirst(); + + assertThat(method).isPresent(); + assertThat(method.orElseThrow().getAnnotation(Transactional.class)).isNotNull(); + } + + @Test + void reservesClaimsAssignsAndReloadsInOrder() { + InboundPlanningResult planned = ready("SPACE-1"); + String reservationId = InboundReservationIds.forJob("J-1"); + when(facade.reserveInbound(reservationId, "01", "P-1", planned)) + .thenReturn(new InboundReservationOutcome("RESERVED", ReservationResult.reserved(reservationId))); + when(algorithmMapper.claimInboundSpace(reservationId, "01", "LANE-1", "SPACE-1", "TRAY-1")) + .thenReturn(1); + when(algorithmMapper.assignInboundJob("J-1", "SPACE-1")).thenReturn(1); + MydoJob committed = new MydoJob(); + committed.setJobId("J-1"); + when(jobMapper.selectInJobByTaskNo("T-1")).thenReturn(committed); + + assertThat(transaction.reserveAndCommit(job, "P-1", planned)).isSameAs(committed); + + var order = inOrder(facade, algorithmMapper, jobMapper); + order.verify(facade).reserveInbound(reservationId, "01", "P-1", planned); + order.verify(algorithmMapper).claimInboundSpace(reservationId, "01", "LANE-1", "SPACE-1", "TRAY-1"); + order.verify(algorithmMapper).assignInboundJob("J-1", "SPACE-1"); + order.verify(jobMapper).selectInJobByTaskNo("T-1"); + } + + private InboundPlanningResult ready(String spaceId) { + InboundAssignment assignment = new InboundAssignment("T-1", spaceId, "LANE-1", 5, 1, + InboundLadderRung.CONTINUE, InboundBorrowType.NONE, null, + 80, 70, 75, 80, false, false, "continue project lane"); + return new InboundPlanningResult(InboundPlan.assigned(assignment), VersionToken.numeric(7)); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/InboundTaskContextTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/InboundTaskContextTest.java new file mode 100644 index 0000000..6da382b --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/InboundTaskContextTest.java @@ -0,0 +1,35 @@ +package com.ruoyi.algorithm.wms; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class InboundTaskContextTest { + + @Test + void derivesProjectAndOptionalProductFromWmsJobDetails() { + InboundTaskContext context = InboundTaskContext.from(List.of( + new InboundTaskItem("P-100", "SKU-1", "LOT-1"), + new InboundTaskItem("P-100", "SKU-2", "LOT-1"))); + + assertThat(context.projectNo()).isEqualTo("P-100"); + assertThat(context.productId()).isNull(); + assertThat(context.lotNo()).isEqualTo("LOT-1"); + } + + @Test + void rejectsMissingOrMixedProjectScopeInsteadOfGuessing() { + assertThatThrownBy(() -> InboundTaskContext.from(List.of( + new InboundTaskItem("P-100", "SKU-1", "LOT-1"), + new InboundTaskItem("P-200", "SKU-2", "LOT-1")))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("exactly one project"); + assertThatThrownBy(() -> InboundTaskContext.from(List.of( + new InboundTaskItem(null, "SKU-1", "LOT-1")))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("exactly one project"); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/OutboundWorkflowTransactionTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/OutboundWorkflowTransactionTest.java new file mode 100644 index 0000000..78b9ba2 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/OutboundWorkflowTransactionTest.java @@ -0,0 +1,404 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.algorithm.outbound.FifoDecision; +import com.ruoyi.algorithm.outbound.OutboundAssignment; +import com.ruoyi.algorithm.outbound.OutboundWorkflow; +import com.ruoyi.algorithm.outbound.OutboundWorkflowPhase; +import com.ruoyi.algorithm.outbound.OutboundWorkflowStep; +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.repository.DeepWorkflowMutationResult; +import com.ruoyi.out.outStockout.domain.OutStockout; +import com.ruoyi.out.outStockout.mapper.OutStockoutMapper; +import com.ruoyi.out.outStockoutDetail.domain.OutStockoutDetail; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.transaction.annotation.Transactional; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class OutboundWorkflowTransactionTest { + private WmsAlgorithmMapper mapper; + private OutStockoutMapper stockoutMapper; + private SchedulingFacade facade; + private OutboundWorkflowTransaction transaction; + private OutStockout stockout; + private OutStockoutDetail detail; + private OutboundStockReference targetStock; + private OutboundAssignment assignment; + + @BeforeEach + void setUp() { + mapper = mock(WmsAlgorithmMapper.class); + stockoutMapper = mock(OutStockoutMapper.class); + facade = mock(SchedulingFacade.class); + transaction = new OutboundWorkflowTransaction(mapper, stockoutMapper, facade); + stockout = new OutStockout(); + stockout.setStockoutId("OUT-1"); + stockout.setWarehouseId("01"); + stockout.setExitId("EXIT-1"); + detail = new OutStockoutDetail(); + detail.setStockoutDetailId("OUT-1-1"); + targetStock = new OutboundStockReference("STOCK-T", "TRAY-T", "DEEP-3", "01", "P-1", "SKU-1"); + assignment = deepAssignment(); + when(mapper.selectOutboundWorkflowStartStockForUpdate("STOCK-T")).thenReturn(targetStock); + } + + @Test + void startPersistsEveryStepLocksItsSpacesAndCreatesOnlyFirstMoveJob() { + when(mapper.selectOutboundStocksAtSpace("01", "DEEP-1")) + .thenReturn(List.of(new OutboundStockReference("STOCK-B", "TRAY-B", "DEEP-1", + "01", "P-B", "SKU-B"))); + when(mapper.lockOutboundWorkflowSpace(any())).thenReturn(1); + when(mapper.insertOutboundWorkflow(any())).thenReturn(1); + when(mapper.insertOutboundWorkflowStep(any())).thenReturn(1); + OutboundWorkflowStepState first = step("WF-M1", OutboundWorkflowPhase.MOVE_OUT, + "DEEP-1", "BUFFER-1", 1, "STOCK-B", "TRAY-B", "PENDING", null); + when(mapper.selectNextPendingWorkflowStep("WORKFLOW-1")).thenReturn(first); + when(mapper.insertOutboundWorkflowMoveJob(first)).thenReturn(1); + when(mapper.markOutboundWorkflowStepRunning("WF-M1", "WF-M1")).thenReturn(1); + + OutboundAllocationResult result = transaction.start(stockout, detail, targetStock, assignment); + + assertThat(result.code()).isEqualTo("WORKFLOW_STARTED"); + verify(mapper).insertOutboundWorkflowMoveJob(first); + verify(mapper).markOutboundWorkflowStepRunning("WF-M1", "WF-M1"); + } + + @Test + void shallowCommitLocksAndValidatesTheSelectedLaneBeforeManualAllocation() { + OutboundAssignment shallow = shallowAssignment(); + OutboundStockReference selected = shallowStock(); + when(mapper.selectOutboundShallowCommitStockForUpdate( + "STOCK-S", "01", "SHALLOW-1", "TRAY-S", "P-1")) + .thenReturn(selected); + manualSucceeds(); + + OutboundAllocationResult result = transaction.commitShallow( + stockout, detail, selected, shallow); + + assertThat(result.status()).isEqualTo( + com.ruoyi.algorithm.integration.SchedulingDecisionStatus.READY); + org.mockito.InOrder order = inOrder(mapper, stockoutMapper); + order.verify(mapper).selectOutboundShallowCommitStockForUpdate( + "STOCK-S", "01", "SHALLOW-1", "TRAY-S", "P-1"); + order.verify(stockoutMapper).manualAllot(any()); + } + + @Test + void shallowCommitUsesConfiguredDefaultWarehouseWhenStockoutWarehouseIsBlank() { + stockout.setWarehouseId(null); + when(facade.defaultWarehouseId()).thenReturn("01"); + OutboundAssignment shallow = shallowAssignment(); + OutboundStockReference selected = shallowStock(); + when(mapper.selectOutboundShallowCommitStockForUpdate( + "STOCK-S", "01", "SHALLOW-1", "TRAY-S", "P-1")) + .thenReturn(selected); + manualSucceeds(); + + OutboundAllocationResult result = transaction.commitShallow( + stockout, detail, selected, shallow); + + assertThat(result.status()).isEqualTo( + com.ruoyi.algorithm.integration.SchedulingDecisionStatus.READY); + verify(mapper).selectOutboundShallowCommitStockForUpdate( + "STOCK-S", "01", "SHALLOW-1", "TRAY-S", "P-1"); + } + + @Test + void deepWorkflowUsesConfiguredDefaultWarehouseWhenStockoutWarehouseIsBlank() { + stockout.setWarehouseId(" "); + when(facade.defaultWarehouseId()).thenReturn("01"); + when(mapper.selectOutboundStocksAtSpace("01", "DEEP-1")) + .thenReturn(List.of(new OutboundStockReference("STOCK-B", "TRAY-B", "DEEP-1", + "01", "P-B", "SKU-B"))); + when(mapper.lockOutboundWorkflowSpace(any())).thenReturn(1); + when(mapper.insertOutboundWorkflow(any())).thenReturn(1); + when(mapper.insertOutboundWorkflowStep(any())).thenReturn(1); + OutboundWorkflowStepState first = step("WF-M1", OutboundWorkflowPhase.MOVE_OUT, + "DEEP-1", "BUFFER-1", 1, "STOCK-B", "TRAY-B", "PENDING", null); + when(mapper.selectNextPendingWorkflowStep("WORKFLOW-1")).thenReturn(first); + when(mapper.insertOutboundWorkflowMoveJob(first)).thenReturn(1); + when(mapper.markOutboundWorkflowStepRunning("WF-M1", "WF-M1")).thenReturn(1); + + OutboundAllocationResult result = transaction.start(stockout, detail, targetStock, assignment); + + assertThat(result.status()).isEqualTo( + com.ruoyi.algorithm.integration.SchedulingDecisionStatus.READY); + verify(mapper).selectOutboundStocksAtSpace("01", "DEEP-1"); + } + + @Test + void shallowCommitReturnsWaitingWhenSelectedStockMovedOrBecameLocked() { + OutboundAssignment shallow = shallowAssignment(); + OutboundStockReference selected = shallowStock(); + when(mapper.selectOutboundShallowCommitStockForUpdate( + "STOCK-S", "01", "SHALLOW-1", "TRAY-S", "P-1")) + .thenReturn(null); + + OutboundAllocationResult result = transaction.commitShallow( + stockout, detail, selected, shallow); + + assertThat(result.status()).isNotEqualTo( + com.ruoyi.algorithm.integration.SchedulingDecisionStatus.READY); + assertThat(result.code()).isEqualTo("SHALLOW_COMMIT_CONFLICT"); + verify(stockoutMapper, never()).manualAllot(any()); + } + + @Test + void shallowCommitReturnsWaitingWhenAnOuterLanePositionBecameBlocked() { + OutboundAssignment shallow = shallowAssignment(); + OutboundStockReference selected = shallowStock(); + when(mapper.selectOutboundShallowCommitStockForUpdate( + "STOCK-S", "01", "SHALLOW-1", "TRAY-S", "P-1")) + .thenReturn(null); + + OutboundAllocationResult result = transaction.commitShallow( + stockout, detail, selected, shallow); + + assertThat(result.status()).isEqualTo( + com.ruoyi.algorithm.integration.SchedulingDecisionStatus.WAITING); + assertThat(result.code()).isEqualTo("SHALLOW_COMMIT_CONFLICT"); + verify(stockoutMapper, never()).manualAllot(any()); + } + + @Test + void shallowCommitDefinesOneSpringTransactionBoundary() throws NoSuchMethodException { + Method method = OutboundWorkflowTransaction.class.getDeclaredMethod( + "commitShallow", OutStockout.class, OutStockoutDetail.class, + OutboundStockReference.class, OutboundAssignment.class); + + assertThat(method.getAnnotation(Transactional.class)).isNotNull(); + } + + @Test + void completingMoveOutCreatesTheDependentOutboundJob() { + OutboundWorkflowStepState move = step("WF-M1", OutboundWorkflowPhase.MOVE_OUT, + "DEEP-1", "BUFFER-1", 1, "STOCK-B", "TRAY-B", "RUNNING", "WF-M1"); + when(mapper.selectOutboundWorkflowStepByJobId("WF-M1")).thenReturn(move); + when(mapper.countStockAtSpaceByTray("BUFFER-1", "TRAY-B")).thenReturn(1); + when(mapper.markOutboundWorkflowStepCompleted("WF-M1")).thenReturn(1); + OutboundWorkflowStepState outbound = step("WF-O", OutboundWorkflowPhase.OUTBOUND, + "DEEP-3", null, 2, "STOCK-T", "TRAY-T", "PENDING", null); + when(mapper.selectNextPendingWorkflowStep("WORKFLOW-1")).thenReturn(outbound); + when(mapper.unlockOutboundWorkflowSpace("WORKFLOW-1", "01", "DEEP-3")).thenReturn(1); + manualSucceeds(); + when(mapper.selectActiveOutboundJobId("STOCK-T", "OUT-1-1")).thenReturn("JOB-O"); + when(mapper.markOutboundWorkflowStepRunning("WF-O", "JOB-O")).thenReturn(1); + + OutboundWorkflowAdvance result = transaction.completeJob("WF-M1"); + + assertThat(result.matched()).isTrue(); + assertThat(result.workflowCompleted()).isFalse(); + verify(stockoutMapper).manualAllot(any()); + verify(mapper).markOutboundWorkflowStepRunning("WF-O", "JOB-O"); + } + + @Test + void completingMoveOutCreatesTheNextConsecutiveMoveOutJob() { + OutboundWorkflowStepState firstMove = step("WF-M1", OutboundWorkflowPhase.MOVE_OUT, + "DEEP-1", "BUFFER-1", 1, "STOCK-B1", "TRAY-B1", "RUNNING", "WF-M1"); + when(mapper.selectOutboundWorkflowStepByJobId("WF-M1")).thenReturn(firstMove); + when(mapper.countStockAtSpaceByTray("BUFFER-1", "TRAY-B1")).thenReturn(1); + when(mapper.markOutboundWorkflowStepCompleted("WF-M1")).thenReturn(1); + OutboundWorkflowStepState secondMove = step("WF-M2", OutboundWorkflowPhase.MOVE_OUT, + "DEEP-2", "BUFFER-2", 2, "STOCK-B2", "TRAY-B2", "PENDING", null); + when(mapper.selectNextPendingWorkflowStep("WORKFLOW-1")).thenReturn(secondMove); + when(mapper.insertOutboundWorkflowMoveJob(secondMove)).thenReturn(1); + when(mapper.markOutboundWorkflowStepRunning("WF-M2", "WF-M2")).thenReturn(1); + + OutboundWorkflowAdvance result = transaction.completeJob("WF-M1"); + + assertThat(result.matched()).isTrue(); + assertThat(result.workflowCompleted()).isFalse(); + verify(mapper).insertOutboundWorkflowMoveJob(secondMove); + verify(mapper).markOutboundWorkflowStepRunning("WF-M2", "WF-M2"); + } + + @Test + void duplicateJobCallbackIsAnIdempotentNoOp() { + when(mapper.selectOutboundWorkflowStepByJobId("WF-M1")).thenReturn(null); + + OutboundWorkflowAdvance result = transaction.completeJob("WF-M1"); + + assertThat(result.matched()).isFalse(); + verify(mapper, never()).markOutboundWorkflowStepCompleted(any()); + verify(mapper, never()).insertOutboundWorkflowMoveJob(any()); + } + + @Test + void duplicateOutboundConfirmationIsAnIdempotentNoOp() { + when(mapper.selectOutboundWorkflowStepForTray("TRAY-T")).thenReturn(null); + + OutboundWorkflowAdvance result = transaction.confirmOutbound("TRAY-T"); + + assertThat(result.matched()).isFalse(); + verify(mapper, never()).markOutboundWorkflowStepCompleted(any()); + verify(mapper, never()).insertOutboundWorkflowMoveJob(any()); + } + + @Test + void outboundConfirmationCreatesRestoreAndFinalRestoreCompletesWorkflow() { + OutboundWorkflowStepState outbound = step("WF-O", OutboundWorkflowPhase.OUTBOUND, + "DEEP-3", null, 2, "STOCK-T", "TRAY-T", "AT_EXIT", "JOB-O"); + when(mapper.selectOutboundWorkflowStepForTray("TRAY-T")).thenReturn(outbound); + when(mapper.countStockAtSpaceByTray("DEEP-3", "TRAY-T")).thenReturn(0); + when(mapper.markOutboundWorkflowStepCompleted("WF-O")).thenReturn(1); + OutboundWorkflowStepState restore = step("WF-R1", OutboundWorkflowPhase.RESTORE, + "BUFFER-1", "DEEP-1", 3, "STOCK-B", "TRAY-B", "PENDING", null); + when(mapper.selectNextPendingWorkflowStep("WORKFLOW-1")).thenReturn(restore); + when(mapper.relockOutboundWorkflowSpace("WORKFLOW-1", "01", "DEEP-1")).thenReturn(1); + when(mapper.insertOutboundWorkflowMoveJob(restore)).thenReturn(1); + when(mapper.markOutboundWorkflowStepRunning("WF-R1", "WF-R1")).thenReturn(1); + + OutboundWorkflowAdvance afterConfirmation = transaction.confirmOutbound("TRAY-T"); + + assertThat(afterConfirmation.workflowCompleted()).isFalse(); + verify(mapper).insertOutboundWorkflowMoveJob(restore); + + OutboundWorkflowStepState runningRestore = step("WF-R1", OutboundWorkflowPhase.RESTORE, + "BUFFER-1", "DEEP-1", 3, "STOCK-B", "TRAY-B", "RUNNING", "WF-R1"); + when(mapper.selectOutboundWorkflowStepByJobId("WF-R1")).thenReturn(runningRestore); + when(mapper.countStockAtSpaceByTray("DEEP-1", "TRAY-B")).thenReturn(1); + when(mapper.markOutboundWorkflowStepCompleted("WF-R1")).thenReturn(1); + when(mapper.selectNextPendingWorkflowStep("WORKFLOW-1")).thenReturn(null); + when(mapper.completeOutboundWorkflow("WORKFLOW-1")).thenReturn(1); + when(mapper.unlockOutboundWorkflowSpaces("WORKFLOW-1")).thenReturn(3); + when(facade.releaseDeepWorkflowLock("01", "OUT-1-1", 2)) + .thenReturn(DeepWorkflowMutationResult.succeeded()); + + OutboundWorkflowAdvance completed = transaction.completeJob("WF-R1"); + + assertThat(completed.workflowCompleted()).isTrue(); + verify(mapper).completeOutboundWorkflow("WORKFLOW-1"); + verify(mapper).unlockOutboundWorkflowSpaces("WORKFLOW-1"); + verify(facade).releaseDeepWorkflowLock("01", "OUT-1-1", 2); + } + + @Test + void wholeTrayConfirmationRelocksOutboundSourceBeforeCreatingFirstRestore() { + OutboundWorkflowStepState outbound = step("WF-O", OutboundWorkflowPhase.OUTBOUND, + "DEEP-3", null, 2, "STOCK-T", "TRAY-T", "AT_EXIT", "JOB-O"); + when(mapper.selectOutboundWorkflowStepForTray("TRAY-T")).thenReturn(outbound); + when(mapper.countStockAtSpaceByTray("DEEP-3", "TRAY-T")).thenReturn(0); + when(mapper.markOutboundWorkflowStepCompleted("WF-O")).thenReturn(1); + OutboundWorkflowStepState restore = step("WF-R1", OutboundWorkflowPhase.RESTORE, + "BUFFER-1", "DEEP-3", 3, "STOCK-B", "TRAY-B", "PENDING", null); + when(mapper.selectNextPendingWorkflowStep("WORKFLOW-1")).thenReturn(restore); + when(mapper.relockOutboundWorkflowSpace("WORKFLOW-1", "01", "DEEP-3")).thenReturn(1); + when(mapper.insertOutboundWorkflowMoveJob(restore)).thenReturn(1); + when(mapper.markOutboundWorkflowStepRunning("WF-R1", "WF-R1")).thenReturn(1); + + OutboundWorkflowAdvance result = transaction.confirmOutbound("TRAY-T"); + + assertThat(result.matched()).isTrue(); + org.mockito.InOrder order = inOrder(mapper); + order.verify(mapper).countStockAtSpaceByTray("DEEP-3", "TRAY-T"); + order.verify(mapper).relockOutboundWorkflowSpace("WORKFLOW-1", "01", "DEEP-3"); + order.verify(mapper).insertOutboundWorkflowMoveJob(restore); + } + + @Test + void startRejectsAStaleTargetStockAfterLockingAndRereadingIt() { + OutboundStockReference movedStock = new OutboundStockReference( + "STOCK-T", "TRAY-T", "OTHER-SPACE", "01", "P-1", "SKU-1"); + when(mapper.selectOutboundWorkflowStartStockForUpdate("STOCK-T")).thenReturn(movedStock); + + assertThatThrownBy(() -> transaction.start(stockout, detail, targetStock, assignment)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("changed after workflow planning"); + + verify(mapper, never()).insertOutboundWorkflow(any()); + } + + @Test + void staleRelocationSourceOrTargetDoesNotMarkTheStepRunning() { + OutboundWorkflowStepState move = step("WF-M1", OutboundWorkflowPhase.MOVE_OUT, + "DEEP-1", "BUFFER-1", 1, "STOCK-B", "TRAY-B", "RUNNING", "WF-M1"); + when(mapper.selectOutboundWorkflowStepByJobId("WF-M1")).thenReturn(move); + when(mapper.countStockAtSpaceByTray("BUFFER-1", "TRAY-B")).thenReturn(1); + when(mapper.markOutboundWorkflowStepCompleted("WF-M1")).thenReturn(1); + OutboundWorkflowStepState nextMove = step("WF-M2", OutboundWorkflowPhase.MOVE_OUT, + "DEEP-2", "BUFFER-2", 2, "STOCK-B2", "TRAY-B2", "PENDING", null); + when(mapper.selectNextPendingWorkflowStep("WORKFLOW-1")).thenReturn(nextMove); + when(mapper.insertOutboundWorkflowMoveJob(nextMove)).thenReturn(0); + + assertThatThrownBy(() -> transaction.completeJob("WF-M1")) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("create relocation job WF-M2"); + + verify(mapper, never()).markOutboundWorkflowStepRunning("WF-M2", "WF-M2"); + } + + @Test + void finalFloorReleaseFailureFailsTheTransactionForCallbackReplay() { + OutboundWorkflowStepState restore = step("WF-R1", OutboundWorkflowPhase.RESTORE, + "BUFFER-1", "DEEP-1", 3, "STOCK-B", "TRAY-B", "RUNNING", "WF-R1"); + when(mapper.selectOutboundWorkflowStepByJobId("WF-R1")).thenReturn(restore); + when(mapper.countStockAtSpaceByTray("DEEP-1", "TRAY-B")).thenReturn(1); + when(mapper.markOutboundWorkflowStepCompleted("WF-R1")).thenReturn(1); + when(mapper.selectNextPendingWorkflowStep("WORKFLOW-1")).thenReturn(null); + when(mapper.completeOutboundWorkflow("WORKFLOW-1")).thenReturn(1); + when(mapper.unlockOutboundWorkflowSpaces("WORKFLOW-1")).thenReturn(3); + when(facade.releaseDeepWorkflowLock("01", "OUT-1-1", 2)) + .thenReturn(DeepWorkflowMutationResult.unchanged()); + + assertThatThrownBy(() -> transaction.completeJob("WF-R1")) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("floor lock was not released"); + } + + private OutboundWorkflowStepState step(String id, OutboundWorkflowPhase phase, String source, + String target, int number, String stockId, String tray, String status, String jobId) { + return new OutboundWorkflowStepState(id, "WORKFLOW-1", "OUT-1-1", "01", 2, + "OUT-1-1", "EXIT-1", phase.name(), source, target, number, 3, + number == 1 ? null : number == 2 ? "WF-M1" : "WF-O", stockId, tray, status, jobId); + } + + private OutboundAssignment deepAssignment() { + OutboundWorkflow workflow = new OutboundWorkflow("WORKFLOW-1", "DEEP-3", "LANE-1", 2, + List.of( + new OutboundWorkflowStep("WF-M1", OutboundWorkflowPhase.MOVE_OUT, + "DEEP-1", "BUFFER-1", 1, 3, null), + new OutboundWorkflowStep("WF-O", OutboundWorkflowPhase.OUTBOUND, + "DEEP-3", null, 2, 3, "WF-M1"), + new OutboundWorkflowStep("WF-R1", OutboundWorkflowPhase.RESTORE, + "BUFFER-1", "DEEP-1", 3, 3, "WF-O")), + List.of("DEEP-1", "DEEP-3"), List.of("BUFFER-1"), "RELEASE_AFTER_FINAL_RESTORE"); + return new OutboundAssignment("OUT-1-1", "TRAY-T", "P-1", "SKU-1", "DEEP-3", 2, + true, List.of("DEEP-1"), List.of("TRAY-B"), false, 70, 60, 65, + FifoDecision.off(), Optional.of(workflow), "deep"); + } + + private OutboundAssignment shallowAssignment() { + return new OutboundAssignment("OUT-1-1", "TRAY-S", "P-1", "SKU-1", "SHALLOW-1", 1, + true, List.of(), List.of(), false, 80, 90, 85, + FifoDecision.off(), Optional.empty(), "shallow"); + } + + private OutboundStockReference shallowStock() { + return new OutboundStockReference( + "STOCK-S", "TRAY-S", "SHALLOW-1", "01", "P-1", "SKU-1"); + } + + private void manualSucceeds() { + doAnswer(invocation -> { + HashMap values = invocation.getArgument(0); + values.put("v_result", "10"); + values.put("v_resultmsg", "ok"); + return null; + }).when(stockoutMapper).manualAllot(any()); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/PersistentOutboundWorkflowCoordinatorTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/PersistentOutboundWorkflowCoordinatorTest.java new file mode 100644 index 0000000..e7b2aaa --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/PersistentOutboundWorkflowCoordinatorTest.java @@ -0,0 +1,158 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.integration.SchedulingMode; +import com.ruoyi.algorithm.integration.SchedulingRoutingPolicy; +import com.ruoyi.algorithm.outbound.FifoDecision; +import com.ruoyi.algorithm.outbound.OutboundAssignment; +import com.ruoyi.algorithm.outbound.OutboundWorkflow; +import com.ruoyi.algorithm.outbound.OutboundWorkflowPhase; +import com.ruoyi.algorithm.outbound.OutboundWorkflowStep; +import com.ruoyi.algorithm.repository.DeepWorkflowMutationResult; +import com.ruoyi.out.outStockout.domain.OutStockout; +import com.ruoyi.out.outStockoutDetail.domain.OutStockoutDetail; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +class PersistentOutboundWorkflowCoordinatorTest { + private SchedulingFacade facade; + private OutboundWorkflowTransaction transaction; + private PersistentOutboundWorkflowCoordinator coordinator; + private OutStockout stockout; + private OutStockoutDetail detail; + private OutboundStockReference stock; + private OutboundAssignment assignment; + + @BeforeEach + void setUp() { + facade = mock(SchedulingFacade.class); + transaction = mock(OutboundWorkflowTransaction.class); + coordinator = new PersistentOutboundWorkflowCoordinator(facade, transaction); + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false)); + stockout = new OutStockout(); + stockout.setWarehouseId("01"); + stockout.setExitId("EXIT-1"); + detail = new OutStockoutDetail(); + detail.setStockoutDetailId("OUT-1-1"); + stock = new OutboundStockReference("STOCK-T", "TRAY-T", "DEEP-3", "01", "P-1", "SKU-1"); + assignment = deepAssignment(); + } + + @Test + void acquiresFloorLockBeforePersistingAndStartingWorkflow() { + when(facade.acquireDeepWorkflowLock("01", "OUT-1-1", 2)) + .thenReturn(DeepWorkflowMutationResult.succeeded()); + when(transaction.start(stockout, detail, stock, assignment)) + .thenReturn(OutboundAllocationResult.ready("WORKFLOW_STARTED", "started", assignment)); + + OutboundAllocationResult result = coordinator.start(stockout, detail, stock, assignment); + + assertThat(result.code()).isEqualTo("WORKFLOW_STARTED"); + verify(transaction).start(stockout, detail, stock, assignment); + } + + @Test + void returnsWaitingWhenAnotherDeepWorkflowOwnsTheFloor() { + when(facade.acquireDeepWorkflowLock("01", "OUT-1-1", 2)) + .thenReturn(DeepWorkflowMutationResult.unchanged()); + + OutboundAllocationResult result = coordinator.start(stockout, detail, stock, assignment); + + assertThat(result.status()).isEqualTo(com.ruoyi.algorithm.integration.SchedulingDecisionStatus.WAITING); + assertThat(result.code()).isEqualTo("WAITING_CHANNEL"); + verify(transaction, never()).start(stockout, detail, stock, assignment); + } + + @Test + void finalStepCompletionDoesNotReleaseTheFloorOutsideTheTransaction() { + OutboundWorkflowAdvance completed = OutboundWorkflowAdvance.completed( + new OutboundWorkflowRuntime("WORKFLOW-1", "OUT-1-1", "01", 2)); + when(transaction.completeJob("JOB-R1")).thenReturn(completed); + + OutboundWorkflowAdvance result = coordinator.onJobFinished("JOB-R1"); + + assertThat(result.workflowCompleted()).isTrue(); + verify(facade, never()).releaseDeepWorkflowLock("01", "OUT-1-1", 2); + } + + @Test + void sameOwnerRetryReturnsReadyWithoutReleasingTheActiveWorkflowLock() { + when(facade.acquireDeepWorkflowLock("01", "OUT-1-1", 2)) + .thenReturn(DeepWorkflowMutationResult.succeeded()); + when(transaction.start(stockout, detail, stock, assignment)) + .thenThrow(new IllegalStateException("duplicate workflow")); + when(transaction.hasActiveWorkflow("OUT-1-1", "01", 2)).thenReturn(true); + + OutboundAllocationResult result = coordinator.start(stockout, detail, stock, assignment); + + assertThat(result.status()).isEqualTo(com.ruoyi.algorithm.integration.SchedulingDecisionStatus.READY); + assertThat(result.code()).isEqualTo("WORKFLOW_ALREADY_ACTIVE"); + verify(facade, never()).releaseDeepWorkflowLock("01", "OUT-1-1", 2); + } + + @Test + void genuinelyNewFailedStartReleasesItsNewlyAcquiredFloorLock() { + IllegalStateException failure = new IllegalStateException("start failed"); + when(facade.acquireDeepWorkflowLock("01", "OUT-1-1", 2)) + .thenReturn(DeepWorkflowMutationResult.succeeded()); + when(transaction.start(stockout, detail, stock, assignment)).thenThrow(failure); + when(transaction.hasActiveWorkflow("OUT-1-1", "01", 2)).thenReturn(false); + when(facade.releaseDeepWorkflowLock("01", "OUT-1-1", 2)) + .thenReturn(DeepWorkflowMutationResult.succeeded()); + + assertThatThrownBy(() -> coordinator.start(stockout, detail, stock, assignment)) + .isSameAs(failure); + + verify(facade).releaseDeepWorkflowLock("01", "OUT-1-1", 2); + } + + @ParameterizedTest + @EnumSource(value = SchedulingMode.class, names = {"LEGACY", "SHADOW"}) + void nonActiveJobCallbackDoesNotQueryWorkflowTables(SchedulingMode mode) { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(mode, false)); + + OutboundWorkflowAdvance result = coordinator.onJobFinished("JOB-IGNORED"); + + assertThat(result).isEqualTo(OutboundWorkflowAdvance.noMatch()); + verifyNoInteractions(transaction); + } + + @ParameterizedTest + @EnumSource(value = SchedulingMode.class, names = {"LEGACY", "SHADOW"}) + void nonActiveConfirmationDoesNotQueryWorkflowTables(SchedulingMode mode) { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(mode, false)); + + OutboundWorkflowAdvance result = coordinator.confirmOutbound("TRAY-IGNORED"); + + assertThat(result).isEqualTo(OutboundWorkflowAdvance.noMatch()); + verifyNoInteractions(transaction); + } + + private OutboundAssignment deepAssignment() { + OutboundWorkflow workflow = new OutboundWorkflow("WORKFLOW-1", "DEEP-3", "LANE-1", 2, + List.of( + new OutboundWorkflowStep("WF-M1", OutboundWorkflowPhase.MOVE_OUT, + "DEEP-1", "BUFFER-1", 1, 3, null), + new OutboundWorkflowStep("WF-O", OutboundWorkflowPhase.OUTBOUND, + "DEEP-3", null, 2, 3, "WF-M1"), + new OutboundWorkflowStep("WF-R1", OutboundWorkflowPhase.RESTORE, + "BUFFER-1", "DEEP-1", 3, 3, "WF-O")), + List.of("DEEP-1", "DEEP-3"), List.of("BUFFER-1"), "RELEASE_AFTER_FINAL_RESTORE"); + return new OutboundAssignment("OUT-1-1", "TRAY-T", "P-1", "SKU-1", "DEEP-3", 2, + true, List.of("DEEP-1"), List.of("TRAY-B"), false, 70, 60, 65, + FifoDecision.off(), Optional.of(workflow), "deep"); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/WmsAlgorithmMapperRegistrationTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/WmsAlgorithmMapperRegistrationTest.java new file mode 100644 index 0000000..03be1bd --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/WmsAlgorithmMapperRegistrationTest.java @@ -0,0 +1,21 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.framework.config.ApplicationConfig; +import org.apache.ibatis.annotations.Mapper; +import org.junit.jupiter.api.Test; +import org.mybatis.spring.annotation.MapperScan; + +import static org.assertj.core.api.Assertions.assertThat; + +class WmsAlgorithmMapperRegistrationTest { + @Test + void applicationScansTheAlgorithmMapperPackage() { + MapperScan[] mapperScans = ApplicationConfig.class.getAnnotationsByType(MapperScan.class); + + assertThat(WmsAlgorithmMapper.class).hasAnnotation(Mapper.class); + assertThat(mapperScans).anySatisfy(mapperScan -> { + assertThat(mapperScan.basePackages()).contains("com.ruoyi.algorithm.wms"); + assertThat(mapperScan.annotationClass()).isEqualTo(Mapper.class); + }); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/WmsInboundAllocationServiceTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/WmsInboundAllocationServiceTest.java new file mode 100644 index 0000000..ffe5a31 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/WmsInboundAllocationServiceTest.java @@ -0,0 +1,248 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.algorithm.inbound.InboundAssignment; +import com.ruoyi.algorithm.inbound.InboundBorrowType; +import com.ruoyi.algorithm.inbound.InboundLadderRung; +import com.ruoyi.algorithm.inbound.InboundPlan; +import com.ruoyi.algorithm.inbound.InboundRequest; +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.integration.SchedulingMode; +import com.ruoyi.algorithm.integration.SchedulingRoutingPolicy; +import com.ruoyi.algorithm.repository.VersionToken; +import com.ruoyi.algorithm.repository.ReservationResult; +import com.ruoyi.algorithm.service.InboundPlanningResult; +import com.ruoyi.algorithm.service.InboundReservationOutcome; +import com.ruoyi.algorithm.wms.tidy.ExecutionAdmissionService; +import com.ruoyi.algorithm.wms.tidy.ExecutionBlockedByTidyModeException; +import com.ruoyi.algorithm.wms.tidy.ExecutionWorkType; +import com.ruoyi.algorithm.wms.tidy.TidyEffectiveState; +import com.ruoyi.job.mydojob.domain.MydoJob; +import com.ruoyi.job.mydojob.mapper.MydoJobMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +class WmsInboundAllocationServiceTest { + private SchedulingFacade facade; + private WmsAlgorithmMapper algorithmMapper; + private MydoJobMapper jobMapper; + private InboundAllocationTransaction transaction; + private ExecutionAdmissionService admission; + private WmsInboundAllocationService service; + private MydoJob job; + + @BeforeEach + void setUp() { + facade = mock(SchedulingFacade.class); + algorithmMapper = mock(WmsAlgorithmMapper.class); + jobMapper = mock(MydoJobMapper.class); + transaction = mock(InboundAllocationTransaction.class); + admission = mock(ExecutionAdmissionService.class); + service = new WmsInboundAllocationService(facade, algorithmMapper, jobMapper, transaction, admission); + job = new MydoJob(); + job.setJobId("J-1"); + job.setTaskNo("T-1"); + job.setTrayCode("TRAY-1"); + job.setWarehouseId("01"); + when(algorithmMapper.selectInboundTaskItems("J-1")) + .thenReturn(List.of(new InboundTaskItem("P-1", "SKU-1", "LOT-1"))); + } + + @Test + void manualTidyModeBlocksInitialAllocationBeforeAnyRouterRuns() { + doThrow(new ExecutionBlockedByTidyModeException(TidyEffectiveState.TIDY_ACTIVE, + ExecutionWorkType.INBOUND)) + .when(admission).assertAllowed("01", ExecutionWorkType.INBOUND); + + assertThatThrownBy(() -> service.allocate(job, "D-1")) + .isInstanceOf(ExecutionBlockedByTidyModeException.class); + + verifyNoInteractions(facade, jobMapper, transaction); + verify(algorithmMapper, never()).selectInboundTaskItems(any()); + } + + @Test + void manualTidyModeBlocksReallocationBeforeOldTargetIsReleased() { + job.setCargoSpaceId("OLD-SPACE"); + doThrow(new ExecutionBlockedByTidyModeException(TidyEffectiveState.ENTERING_TIDY, + ExecutionWorkType.INBOUND)) + .when(admission).assertAllowed("01", ExecutionWorkType.INBOUND); + + assertThatThrownBy(() -> service.reallocate(job, "D-1")) + .isInstanceOf(ExecutionBlockedByTidyModeException.class); + + verifyNoInteractions(facade, jobMapper, transaction); + } + + @Test + void completionCallbackDoesNotUseCreationAdmissionGate() { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false)); + when(facade.releaseInboundReservation("01", InboundReservationIds.forJob("J-1"))) + .thenReturn(ReservationResult.released(InboundReservationIds.forJob("J-1"))); + + service.completeInbound(job); + + verifyNoInteractions(admission); + verify(facade).releaseInboundReservation("01", InboundReservationIds.forJob("J-1")); + } + + @Test + void shadowPlansButKeepsLegacyStoredProcedureAsBusinessWriter() { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.SHADOW, false)); + when(facade.planInbound(eq("01"), any(InboundRequest.class))).thenReturn(ready("JAVA-SPACE")); + MydoJob legacyResult = copyJob("LEGACY-SPACE"); + doAnswer(invocation -> { + var parameters = invocation.getArgument(0, java.util.HashMap.class); + parameters.put("v_result", 10); + parameters.put("v_resultmsg", "ok"); + return null; + }).when(jobMapper).allotInJobSpace(any()); + when(jobMapper.selectInJobByTaskNo("T-1")).thenReturn(legacyResult); + + InboundAllocationResult result = service.allocate(job, "D-1"); + + assertThat(result.success()).isTrue(); + assertThat(result.job().getCargoSpaceId()).isEqualTo("LEGACY-SPACE"); + verify(facade).planInbound(eq("01"), any(InboundRequest.class)); + verify(jobMapper).allotInJobSpace(any()); + verify(transaction, never()).reserveAndCommit(any(), any(), any()); + } + + @Test + void activeRejectionNeverFallsBackToLegacy() { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, true)); + when(facade.planInbound(eq("01"), any(InboundRequest.class))) + .thenReturn(new InboundPlanningResult(InboundPlan.rejected( + new com.ruoyi.algorithm.inbound.InboundRejection( + com.ruoyi.algorithm.inbound.InboundRejectionCode.NO_FEASIBLE_LOCATION, + "no legal space", "P-1", "SKU-1", "LOT-1", List.of())), null)); + + InboundAllocationResult result = service.allocate(job, "D-1"); + + assertThat(result.success()).isFalse(); + assertThat(result.code()).isEqualTo("NO_FEASIBLE_LOCATION"); + verify(jobMapper, never()).allotInJobSpace(any()); + verify(transaction, never()).reserveAndCommit(any(), any(), any()); + } + + @Test + void activeReadyPlanCommitsThroughSeparateTransactionBoundary() { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false)); + InboundPlanningResult plan = ready("JAVA-SPACE"); + when(facade.planInbound(eq("01"), any(InboundRequest.class))).thenReturn(plan); + MydoJob activeResult = copyJob("JAVA-SPACE"); + when(transaction.reserveAndCommit(job, "P-1", plan)).thenReturn(activeResult); + + InboundAllocationResult result = service.allocate(job, "D-1"); + + assertThat(result.success()).isTrue(); + assertThat(result.job().getCargoSpaceId()).isEqualTo("JAVA-SPACE"); + verify(facade, never()).reserveInbound(any(), any(), any(), any()); + verify(transaction).reserveAndCommit(job, "P-1", plan); + verify(jobMapper, never()).allotInJobSpace(any()); + } + + @Test + void activeReadyPlanDoesNotReserveOutsideTheCommitTransaction() { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false)); + InboundPlanningResult plan = ready("JAVA-SPACE"); + when(facade.planInbound(eq("01"), any(InboundRequest.class))).thenReturn(plan); + when(transaction.reserveAndCommit(job, "P-1", plan)).thenReturn(copyJob("JAVA-SPACE")); + + InboundAllocationResult result = service.allocate(job, "D-1"); + + assertThat(result.success()).isTrue(); + verify(facade, never()).reserveInbound(any(), any(), any(), any()); + } + + @Test + void reallocateReleasesOldAssignmentBeforeRunningTheConfiguredRouter() { + job.setCargoSpaceId("OLD-SPACE"); + job.setEntranceId("PORT-1"); + MydoJob cleared = copyJob(null); + when(transaction.release(job)).thenReturn(cleared); + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.LEGACY, false)); + MydoJob allocated = copyJob("NEW-SPACE"); + doAnswer(invocation -> { + var parameters = invocation.getArgument(0, java.util.HashMap.class); + parameters.put("v_result", 10); + parameters.put("v_resultmsg", "ok"); + return null; + }).when(jobMapper).allotInJobSpace(any()); + when(jobMapper.selectInJobByTaskNo("T-1")).thenReturn(allocated); + + InboundAllocationResult result = service.reallocate(job, "PORT-1"); + + assertThat(result.success()).isTrue(); + assertThat(result.job().getCargoSpaceId()).isEqualTo("NEW-SPACE"); + verify(transaction).release(job); + verify(facade, never()).releaseInboundReservation(any(), any()); + verify(jobMapper).allotInJobSpace(any()); + } + + @Test + void activeReallocationReleasesTheDeterministicReservationBeforePlanningAgain() { + job.setCargoSpaceId("OLD-SPACE"); + MydoJob cleared = copyJob(null); + when(transaction.release(job)).thenReturn(cleared); + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false)); + when(facade.releaseInboundReservation("01", InboundReservationIds.forJob("J-1"))) + .thenReturn(ReservationResult.released(InboundReservationIds.forJob("J-1"))); + InboundPlanningResult plan = ready("NEW-SPACE"); + when(facade.planInbound(eq("01"), any(InboundRequest.class))).thenReturn(plan); + MydoJob allocated = copyJob("NEW-SPACE"); + when(transaction.reserveAndCommit(cleared, "P-1", plan)).thenReturn(allocated); + + InboundAllocationResult result = service.reallocate(job, "PORT-1"); + + assertThat(result.success()).isTrue(); + org.mockito.InOrder order = org.mockito.Mockito.inOrder(transaction, facade); + order.verify(transaction).release(job); + order.verify(facade).releaseInboundReservation("01", InboundReservationIds.forJob("J-1")); + order.verify(facade).planInbound(eq("01"), any(InboundRequest.class)); + } + + @Test + void reallocateStopsWhenOldAssignmentCannotBeSafelyReleased() { + job.setCargoSpaceId("OLD-SPACE"); + when(transaction.release(job)).thenThrow(new org.springframework.dao.CannotAcquireLockException( + "Old inbound target contains stock")); + + InboundAllocationResult result = service.reallocate(job, "PORT-1"); + + assertThat(result.success()).isFalse(); + assertThat(result.code()).isEqualTo("REASSIGNMENT_CONFLICT"); + verify(facade, never()).releaseInboundReservation(any(), any()); + verify(jobMapper, never()).allotInJobSpace(any()); + } + + private InboundPlanningResult ready(String spaceId) { + InboundAssignment assignment = new InboundAssignment("T-1", spaceId, "LANE-1", 5, 1, + InboundLadderRung.CONTINUE, InboundBorrowType.NONE, null, + 80, 70, 75, 80, false, false, "continue project lane"); + return new InboundPlanningResult(InboundPlan.assigned(assignment), VersionToken.numeric(7)); + } + + private MydoJob copyJob(String spaceId) { + MydoJob value = new MydoJob(); + value.setJobId(job.getJobId()); + value.setTaskNo(job.getTaskNo()); + value.setTrayCode(job.getTrayCode()); + value.setWarehouseId(job.getWarehouseId()); + value.setCargoSpaceId(spaceId); + return value; + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/WmsOutboundAllocationServiceTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/WmsOutboundAllocationServiceTest.java new file mode 100644 index 0000000..985bde4 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/WmsOutboundAllocationServiceTest.java @@ -0,0 +1,296 @@ +package com.ruoyi.algorithm.wms; + +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.integration.SchedulingMode; +import com.ruoyi.algorithm.integration.SchedulingRoutingPolicy; +import com.ruoyi.algorithm.outbound.FifoDecision; +import com.ruoyi.algorithm.outbound.OutboundAssignment; +import com.ruoyi.algorithm.outbound.OutboundPlan; +import com.ruoyi.algorithm.outbound.OutboundRequest; +import com.ruoyi.algorithm.outbound.OutboundWaiting; +import com.ruoyi.algorithm.outbound.OutboundWaitingCode; +import com.ruoyi.algorithm.outbound.OutboundWorkflow; +import com.ruoyi.algorithm.outbound.OutboundWorkflowPhase; +import com.ruoyi.algorithm.outbound.OutboundWorkflowStep; +import com.ruoyi.algorithm.outbound.TaskCountEstimate; +import com.ruoyi.algorithm.wms.tidy.ExecutionAdmissionService; +import com.ruoyi.algorithm.wms.tidy.ExecutionBlockedByTidyModeException; +import com.ruoyi.algorithm.wms.tidy.ExecutionWorkType; +import com.ruoyi.algorithm.wms.tidy.TidyEffectiveState; +import com.ruoyi.out.outStockout.domain.OutStockout; +import com.ruoyi.out.outStockout.mapper.OutStockoutMapper; +import com.ruoyi.out.outStockoutDetail.domain.OutStockoutDetail; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +class WmsOutboundAllocationServiceTest { + private SchedulingFacade facade; + private WmsAlgorithmMapper algorithmMapper; + private OutStockoutMapper stockoutMapper; + private OutboundWorkflowCoordinator workflowCoordinator; + private OutboundWorkflowTransaction workflowTransaction; + private ExecutionAdmissionService admission; + private WmsOutboundAllocationService service; + private OutStockout stockout; + private OutStockoutDetail detail; + + @BeforeEach + void setUp() { + facade = mock(SchedulingFacade.class); + algorithmMapper = mock(WmsAlgorithmMapper.class); + stockoutMapper = mock(OutStockoutMapper.class); + workflowCoordinator = mock(OutboundWorkflowCoordinator.class); + workflowTransaction = mock(OutboundWorkflowTransaction.class); + admission = mock(ExecutionAdmissionService.class); + service = new WmsOutboundAllocationService(facade, algorithmMapper, stockoutMapper, + workflowCoordinator, workflowTransaction, admission); + + stockout = new OutStockout(); + stockout.setStockoutId("OUT-1"); + stockout.setWarehouseId("01"); + stockout.setExitId("EXIT-1"); + detail = new OutStockoutDetail(); + detail.setStockoutDetailId("OUT-1-1"); + detail.setStockoutId("OUT-1"); + detail.setSpare4("PROJECT-1"); + detail.setProductId("SKU-IGNORED"); + } + + @Test + void springUsesConstructorThatInjectsAdmissionGate() { + var springConstructor = Arrays.stream(WmsOutboundAllocationService.class.getDeclaredConstructors()) + .filter(constructor -> constructor.isAnnotationPresent(Autowired.class)) + .findFirst() + .orElseThrow(); + + assertThat(springConstructor.getParameterTypes()) + .contains(ExecutionAdmissionService.class); + } + + @Test + void manualTidyModeBlocksProjectAllocationBeforeAnyRouterRuns() { + doThrow(new ExecutionBlockedByTidyModeException(TidyEffectiveState.TIDY_ACTIVE, + ExecutionWorkType.OUTBOUND)) + .when(admission).assertAllowed("01", ExecutionWorkType.OUTBOUND); + + assertThatThrownBy(() -> service.allocateProject(stockout, detail)) + .isInstanceOf(ExecutionBlockedByTidyModeException.class); + + verifyNoInteractions(facade, algorithmMapper, stockoutMapper, workflowCoordinator, + workflowTransaction); + } + + @Test + void manualTidyModeBlocksExactStockAllocationBeforeAnyRouterRuns() { + doThrow(new ExecutionBlockedByTidyModeException(TidyEffectiveState.EXITING_TIDY, + ExecutionWorkType.OUTBOUND)) + .when(admission).assertAllowed("01", ExecutionWorkType.OUTBOUND); + + assertThatThrownBy(() -> service.allocateExactStock(stockout, detail, "STOCK-9")) + .isInstanceOf(ExecutionBlockedByTidyModeException.class); + + verifyNoInteractions(facade, algorithmMapper, stockoutMapper, workflowCoordinator, + workflowTransaction); + } + + @Test + void shadowPlansByProjectOnlyButLeavesBusinessWritesToLegacy() { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.SHADOW, false)); + when(facade.planOutbound(eq("01"), any(OutboundRequest.class))) + .thenReturn(ready(shallowAssignment("SPACE-1", "TRAY-1"))); + legacyAutoSucceeds(); + + OutboundAllocationResult result = service.allocateProject(stockout, detail); + + assertThat(result.status()).isEqualTo(com.ruoyi.algorithm.integration.SchedulingDecisionStatus.READY); + org.mockito.ArgumentCaptor request = org.mockito.ArgumentCaptor.forClass(OutboundRequest.class); + verify(facade).planOutbound(eq("01"), request.capture()); + assertThat(request.getValue().projectNo()).isEqualTo("PROJECT-1"); + assertThat(request.getValue().productId()).isNull(); + assertThat(request.getValue().wholeTrayOrDefault()).isTrue(); + verify(stockoutMapper).autoAllot(any()); + } + + @Test + void activeWaitingNeverFallsBackToLegacy() { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, true)); + when(facade.planOutbound(eq("01"), any(OutboundRequest.class))).thenReturn(OutboundPlan.waiting( + new OutboundWaiting(OutboundWaitingCode.WAITING_RELOCATION_BUFFER, 2, 1, + "two buffers required", true, Map.of()))); + + OutboundAllocationResult result = service.allocateProject(stockout, detail); + + assertThat(result.status()).isEqualTo(com.ruoyi.algorithm.integration.SchedulingDecisionStatus.WAITING); + assertThat(result.code()).isEqualTo("WAITING_RELOCATION_BUFFER"); + verify(stockoutMapper, never()).autoAllot(any()); + verify(stockoutMapper, never()).manualAllot(any()); + } + + @Test + void activeShallowPlanCommitsOnlyTheStockChosenByTheAlgorithm() { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false)); + OutboundAssignment assignment = shallowAssignment("SPACE-1", "TRAY-1"); + when(facade.planOutbound(eq("01"), any(OutboundRequest.class))).thenReturn(ready(assignment)); + OutboundStockReference reference = new OutboundStockReference("STOCK-1", "TRAY-1", "SPACE-1", + "01", "PROJECT-1", "SKU-1"); + when(algorithmMapper.selectOutboundStockReferences("01", "SPACE-1", "TRAY-1", "PROJECT-1")) + .thenReturn(List.of(reference)); + when(workflowTransaction.commitShallow(stockout, detail, reference, assignment)) + .thenReturn(OutboundAllocationResult.ready("READY", "ok", assignment)); + + OutboundAllocationResult result = service.allocateProject(stockout, detail); + + assertThat(result.status()).isEqualTo(com.ruoyi.algorithm.integration.SchedulingDecisionStatus.READY); + verify(workflowTransaction).commitShallow(stockout, detail, reference, assignment); + verify(stockoutMapper, never()).manualAllot(any()); + verify(stockoutMapper, never()).autoAllot(any()); + } + + @Test + void activeShallowPlanUsesFirstStockIdForOnePhysicalTrayWithMultipleDetails() { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false)); + OutboundAssignment assignment = shallowAssignment("SPACE-1", "TRAY-1"); + when(facade.planOutbound(eq("01"), any(OutboundRequest.class))).thenReturn(ready(assignment)); + OutboundStockReference second = new OutboundStockReference("STOCK-2", "TRAY-1", "SPACE-1", + "01", "PROJECT-1", "SKU-2"); + OutboundStockReference first = new OutboundStockReference("STOCK-1", "TRAY-1", "SPACE-1", + "01", "PROJECT-1", "SKU-1"); + when(algorithmMapper.selectOutboundStockReferences("01", "SPACE-1", "TRAY-1", "PROJECT-1")) + .thenReturn(List.of(second, first)); + when(workflowTransaction.commitShallow(stockout, detail, first, assignment)) + .thenReturn(OutboundAllocationResult.ready("READY", "ok", assignment)); + + OutboundAllocationResult result = service.allocateProject(stockout, detail); + + assertThat(result.status()).isEqualTo(com.ruoyi.algorithm.integration.SchedulingDecisionStatus.READY); + verify(workflowTransaction).commitShallow(stockout, detail, first, assignment); + verify(stockoutMapper, never()).manualAllot(any()); + } + + @Test + void activeDeepPlanStartsPersistentWorkflowInsteadOfDirectOutbound() { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false)); + OutboundAssignment assignment = deepAssignment(); + when(facade.planOutbound(eq("01"), any(OutboundRequest.class))).thenReturn(ready(assignment)); + OutboundStockReference reference = new OutboundStockReference("STOCK-T", "TRAY-T", "DEEP-3", + "01", "PROJECT-1", "SKU-1"); + when(algorithmMapper.selectOutboundStockReferences("01", "DEEP-3", "TRAY-T", "PROJECT-1")) + .thenReturn(List.of(reference)); + when(workflowCoordinator.start(stockout, detail, reference, assignment)) + .thenReturn(OutboundAllocationResult.ready("WORKFLOW-1", "Deep workflow started", assignment)); + + OutboundAllocationResult result = service.allocateProject(stockout, detail); + + assertThat(result.status()).isEqualTo(com.ruoyi.algorithm.integration.SchedulingDecisionStatus.READY); + verify(workflowCoordinator).start(stockout, detail, reference, assignment); + verify(workflowTransaction, never()).commitShallow(any(), any(), any(), any()); + verify(stockoutMapper, never()).manualAllot(any()); + } + + @Test + void activeDeepPlanUsesFirstStockIdForOnePhysicalTrayWithMultipleDetails() { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false)); + OutboundAssignment assignment = deepAssignment(); + when(facade.planOutbound(eq("01"), any(OutboundRequest.class))).thenReturn(ready(assignment)); + OutboundStockReference second = new OutboundStockReference("STOCK-2", "TRAY-T", "DEEP-3", + "01", "PROJECT-1", "SKU-2"); + OutboundStockReference first = new OutboundStockReference("STOCK-1", "TRAY-T", "DEEP-3", + "01", "PROJECT-1", "SKU-1"); + when(algorithmMapper.selectOutboundStockReferences("01", "DEEP-3", "TRAY-T", "PROJECT-1")) + .thenReturn(List.of(second, first)); + when(workflowCoordinator.start(stockout, detail, first, assignment)) + .thenReturn(OutboundAllocationResult.ready("WORKFLOW-1", "Deep workflow started", assignment)); + + OutboundAllocationResult result = service.allocateProject(stockout, detail); + + assertThat(result.status()).isEqualTo(com.ruoyi.algorithm.integration.SchedulingDecisionStatus.READY); + verify(workflowCoordinator).start(stockout, detail, first, assignment); + verify(workflowTransaction, never()).commitShallow(any(), any(), any(), any()); + verify(stockoutMapper, never()).manualAllot(any()); + } + + @Test + void exactStockRequestIsValidatedByTrayBeforeManualCommit() { + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false)); + OutboundStockReference selected = new OutboundStockReference("STOCK-9", "TRAY-9", "SPACE-9", + "01", "PROJECT-1", "SKU-9"); + when(algorithmMapper.selectOutboundStockReference("STOCK-9")).thenReturn(selected); + when(facade.planOutbound(eq("01"), any(OutboundRequest.class))) + .thenReturn(ready(shallowAssignment("SPACE-9", "TRAY-9"))); + OutboundAssignment assignment = shallowAssignment("SPACE-9", "TRAY-9"); + when(workflowTransaction.commitShallow(stockout, detail, selected, assignment)) + .thenReturn(OutboundAllocationResult.ready("READY", "ok", assignment)); + + OutboundAllocationResult result = service.allocateExactStock(stockout, detail, "STOCK-9"); + + assertThat(result.status()).isEqualTo(com.ruoyi.algorithm.integration.SchedulingDecisionStatus.READY); + org.mockito.ArgumentCaptor request = org.mockito.ArgumentCaptor.forClass(OutboundRequest.class); + verify(facade).planOutbound(eq("01"), request.capture()); + assertThat(request.getValue().trayNo()).isEqualTo("TRAY-9"); + verify(workflowTransaction).commitShallow(stockout, detail, selected, assignment); + verify(stockoutMapper, never()).manualAllot(any()); + } + + private OutboundPlan ready(OutboundAssignment assignment) { + return OutboundPlan.ready(assignment, new TaskCountEstimate(0, 1, 0, 0)); + } + + private OutboundAssignment shallowAssignment(String spaceId, String trayCode) { + return new OutboundAssignment("OUT-1-1", trayCode, "PROJECT-1", "SKU-1", spaceId, 1, + true, List.of(), List.of(), false, 80, 90, 85, FifoDecision.off(), + Optional.empty(), "outermost project tray"); + } + + private OutboundAssignment deepAssignment() { + List steps = List.of( + new OutboundWorkflowStep("WF-M1", OutboundWorkflowPhase.MOVE_OUT, + "DEEP-1", "BUFFER-1", 1, 3, null), + new OutboundWorkflowStep("WF-O", OutboundWorkflowPhase.OUTBOUND, + "DEEP-3", null, 2, 3, "WF-M1"), + new OutboundWorkflowStep("WF-R1", OutboundWorkflowPhase.RESTORE, + "BUFFER-1", "DEEP-1", 3, 3, "WF-O")); + OutboundWorkflow workflow = new OutboundWorkflow("WORKFLOW-1", "DEEP-3", "LANE-1", 2, + steps, List.of("DEEP-1", "DEEP-3"), List.of("BUFFER-1"), + "RELEASE_AFTER_FINAL_RESTORE"); + return new OutboundAssignment("OUT-1-1", "TRAY-T", "PROJECT-1", "SKU-1", "DEEP-3", 2, + true, List.of("DEEP-1"), List.of("TRAY-B"), false, 75, 60, 67, + FifoDecision.off(), Optional.of(workflow), "deep exact tray"); + } + + private void legacyAutoSucceeds() { + doAnswer(invocation -> { + HashMap values = invocation.getArgument(0); + values.put("v_result", "10"); + values.put("v_resultmsg", "ok"); + return null; + }).when(stockoutMapper).autoAllot(any()); + } + + private void legacyManualSucceeds() { + doAnswer(invocation -> { + HashMap values = invocation.getArgument(0); + values.put("v_result", "10"); + values.put("v_resultmsg", "ok"); + return null; + }).when(stockoutMapper).manualAllot(any()); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/ExecutionAdmissionServiceTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/ExecutionAdmissionServiceTest.java new file mode 100644 index 0000000..3c642e9 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/ExecutionAdmissionServiceTest.java @@ -0,0 +1,78 @@ +package com.ruoyi.algorithm.wms.tidy; + +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class ExecutionAdmissionServiceTest { + @Test + void documentReceiptIsAllowedInEveryState() { + TidyModeService modeService = mock(TidyModeService.class); + ExecutionAdmissionService gate = new ExecutionAdmissionService(modeService); + + for (TidyEffectiveState state : TidyEffectiveState.values()) { + when(modeService.statusForAdmission("01")).thenReturn(snapshot(state)); + assertThatCode(() -> gate.assertAllowed("01", ExecutionWorkType.DOCUMENT_RECEIPT)) + .doesNotThrowAnyException(); + } + } + + @Test + void normalModeAllowsBusinessAndAutomaticTidyButNotManualTidy() { + ExecutionAdmissionService gate = gate(TidyEffectiveState.NORMAL); + + assertThatCode(() -> gate.assertAllowed("01", ExecutionWorkType.INBOUND)).doesNotThrowAnyException(); + assertThatCode(() -> gate.assertAllowed("01", ExecutionWorkType.OUTBOUND)).doesNotThrowAnyException(); + assertThatCode(() -> gate.assertAllowed("01", ExecutionWorkType.OUTBOUND_RELOCATION)).doesNotThrowAnyException(); + assertThatCode(() -> gate.assertAllowed("01", ExecutionWorkType.AUTO_TIDY)).doesNotThrowAnyException(); + assertBlocked(gate, ExecutionWorkType.MANUAL_TIDY, TidyEffectiveState.NORMAL); + } + + @Test + void activeManualModeAllowsOnlyManualTidyAndDocumentReceipt() { + ExecutionAdmissionService gate = gate(TidyEffectiveState.TIDY_ACTIVE); + + assertThatCode(() -> gate.assertAllowed("01", ExecutionWorkType.MANUAL_TIDY)).doesNotThrowAnyException(); + assertBlocked(gate, ExecutionWorkType.INBOUND, TidyEffectiveState.TIDY_ACTIVE); + assertBlocked(gate, ExecutionWorkType.OUTBOUND, TidyEffectiveState.TIDY_ACTIVE); + assertBlocked(gate, ExecutionWorkType.OUTBOUND_RELOCATION, TidyEffectiveState.TIDY_ACTIVE); + assertBlocked(gate, ExecutionWorkType.AUTO_TIDY, TidyEffectiveState.TIDY_ACTIVE); + } + + @Test + void transitionModesBlockNewExecutionWork() { + for (TidyEffectiveState state : new TidyEffectiveState[] { + TidyEffectiveState.ENTERING_TIDY, TidyEffectiveState.EXITING_TIDY}) { + ExecutionAdmissionService gate = gate(state); + for (ExecutionWorkType type : ExecutionWorkType.values()) { + if (type != ExecutionWorkType.DOCUMENT_RECEIPT) { + assertBlocked(gate, type, state); + } + } + } + } + + private ExecutionAdmissionService gate(TidyEffectiveState state) { + TidyModeService modeService = mock(TidyModeService.class); + when(modeService.statusForAdmission("01")).thenReturn(snapshot(state)); + return new ExecutionAdmissionService(modeService); + } + + private void assertBlocked(ExecutionAdmissionService gate, ExecutionWorkType type, + TidyEffectiveState state) { + assertThatThrownBy(() -> gate.assertAllowed("01", type)) + .isInstanceOf(ExecutionBlockedByTidyModeException.class) + .hasMessageContaining(state.name()) + .hasMessageContaining(type.name()); + } + + private TidyModeSnapshot snapshot(TidyEffectiveState state) { + return new TidyModeSnapshot("01", state != TidyEffectiveState.NORMAL, state, + 0, 0, "TEST", 1, "tester", LocalDateTime.of(2026, 7, 22, 10, 0)); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/ReplayExecutionGuardTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/ReplayExecutionGuardTest.java new file mode 100644 index 0000000..0a11c82 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/ReplayExecutionGuardTest.java @@ -0,0 +1,48 @@ +package com.ruoyi.algorithm.wms.tidy; + +import com.ruoyi.algorithm.integration.AlgorithmProperties; +import com.ruoyi.algorithm.integration.SchedulingMode; +import com.ruoyi.algorithm.wms.WmsAlgorithmMapper; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +class ReplayExecutionGuardTest { + @Test + void blankRunIdLeavesNormalShadowStartupUntouched() { + AlgorithmProperties properties = new AlgorithmProperties(); + WmsAlgorithmMapper mapper = mock(WmsAlgorithmMapper.class); + + assertThatCode(() -> new ReplayExecutionGuard(properties, mapper).validate()) + .doesNotThrowAnyException(); + verifyNoInteractions(mapper); + } + + @Test + void replayRequiresActiveWritesAndExactDatabase() { + AlgorithmProperties properties = replayProperties(); + WmsAlgorithmMapper mapper = mock(WmsAlgorithmMapper.class); + + properties.setMode(SchedulingMode.SHADOW); + assertThatThrownBy(() -> new ReplayExecutionGuard(properties, mapper).validate()) + .hasMessageContaining("REPLAY_REQUIRES_ACTIVE_WRITES"); + + properties.setMode(SchedulingMode.ACTIVE); + when(mapper.selectDatabaseName()).thenReturn("other-db", "FT546-wms"); + ReplayExecutionGuard guard = new ReplayExecutionGuard(properties, mapper); + assertThatThrownBy(guard::validate).hasMessageContaining("REPLAY_DATABASE_MISMATCH"); + assertThatCode(guard::validate).doesNotThrowAnyException(); + } + + private AlgorithmProperties replayProperties() { + AlgorithmProperties properties = new AlgorithmProperties(); + properties.setReplayRunId("RUN-1"); + properties.setReplayDatabase("FT546-wms"); + properties.setDatabaseWritesEnabled(true); + return properties; + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyLaneClaimTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyLaneClaimTest.java new file mode 100644 index 0000000..076d2f6 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyLaneClaimTest.java @@ -0,0 +1,33 @@ +package com.ruoyi.algorithm.wms.tidy; + +import org.junit.jupiter.api.Test; + +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDateTime; +import java.util.TimeZone; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +class TidyLaneClaimTest { + + @Test + void preservesSqlServerUtcDatetime2WallClockReturnedByMyBatis() { + TimeZone originalTimeZone = TimeZone.getDefault(); + try { + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai")); + UUID claimToken = UUID.randomUUID(); + LocalDateTime leaseExpiresAt = LocalDateTime.of(2026, 7, 22, 16, 26, 32); + + TidyLaneClaim claim = new TidyLaneClaim( + "01", "LANE-1", 7L, claimToken.toString(), Timestamp.valueOf(leaseExpiresAt)); + + assertThat(claim.claimToken()).isEqualTo(claimToken); + assertThat(claim.leaseExpiresAt()).isEqualTo(leaseExpiresAt); + assertThat(claim.validAt(Instant.parse("2026-07-22T16:25:32Z"))).isTrue(); + } finally { + TimeZone.setDefault(originalTimeZone); + } + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyModeServiceTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyModeServiceTest.java new file mode 100644 index 0000000..7e9b0b4 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyModeServiceTest.java @@ -0,0 +1,109 @@ +package com.ruoyi.algorithm.wms.tidy; + +import com.ruoyi.algorithm.wms.WmsAlgorithmMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class TidyModeServiceTest { + private WmsAlgorithmMapper mapper; + private TidyModeService service; + + @BeforeEach + void setUp() { + mapper = mock(WmsAlgorithmMapper.class); + service = new TidyModeService(mapper); + } + + @Test + void enablingManualModeStartsBusinessDrainThenActivatesTidy() { + TidyModeSnapshot normal = snapshot(false, TidyEffectiveState.NORMAL, 7); + TidyModeSnapshot entering = snapshot(true, TidyEffectiveState.ENTERING_TIDY, 8); + when(mapper.selectTidyModeForUpdate("01")).thenReturn(normal, entering); + when(mapper.setTidyModeRequest("01", true, "ENTERING_TIDY", "MANUAL_MODE_REQUESTED", + "tester", 7)).thenReturn(1); + when(mapper.countActiveBusinessExecution("01")).thenReturn(0); + when(mapper.countActiveManualTidy("01")).thenReturn(0); + when(mapper.setTidyModeRequest("01", true, "TIDY_ACTIVE", "BUSINESS_DRAINED", + "system", 8)).thenReturn(1); + + assertThat(service.requestManualMode("01", true, "tester").effectiveState()) + .isEqualTo(TidyEffectiveState.ENTERING_TIDY); + assertThat(service.reconcile("01").effectiveState()) + .isEqualTo(TidyEffectiveState.TIDY_ACTIVE); + } + + @Test + void disablingManualModeStopsReplenishmentAndReturnsToNormalAfterTidyDrain() { + TidyModeSnapshot active = snapshot(true, TidyEffectiveState.TIDY_ACTIVE, 11); + TidyModeSnapshot exiting = snapshot(false, TidyEffectiveState.EXITING_TIDY, 12); + when(mapper.selectTidyModeForUpdate("01")).thenReturn(active, exiting); + when(mapper.setTidyModeRequest("01", false, "EXITING_TIDY", "MANUAL_MODE_RELEASED", + "tester", 11)).thenReturn(1); + when(mapper.countActiveBusinessExecution("01")).thenReturn(0); + when(mapper.countActiveManualTidy("01")).thenReturn(0); + when(mapper.setTidyModeRequest("01", false, "NORMAL", "TIDY_DRAINED", + "system", 12)).thenReturn(1); + + assertThat(service.requestManualMode("01", false, "tester").effectiveState()) + .isEqualTo(TidyEffectiveState.EXITING_TIDY); + assertThat(service.reconcile("01").effectiveState()) + .isEqualTo(TidyEffectiveState.NORMAL); + } + + @Test + void repeatedEnableOrDisableIsIdempotent() { + TidyModeSnapshot entering = snapshot(true, TidyEffectiveState.ENTERING_TIDY, 3); + TidyModeSnapshot normal = snapshot(false, TidyEffectiveState.NORMAL, 4); + when(mapper.selectTidyModeForUpdate("01")).thenReturn(entering, normal); + + assertThat(service.requestManualMode("01", true, "tester")).isSameAs(entering); + assertThat(service.requestManualMode("01", false, "tester")).isSameAs(normal); + verify(mapper, never()).setTidyModeRequest(anyString(), anyBoolean(), anyString(), + anyString(), anyString(), anyLong()); + } + + @Test + void optimisticVersionFailureDoesNotReturnAFalseState() { + when(mapper.selectTidyModeForUpdate("01")) + .thenReturn(snapshot(false, TidyEffectiveState.NORMAL, 20)); + when(mapper.setTidyModeRequest(anyString(), anyBoolean(), anyString(), anyString(), + anyString(), anyLong())).thenReturn(0); + + assertThatThrownBy(() -> service.requestManualMode("01", true, "tester")) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("TIDY_MODE_VERSION_CONFLICT"); + } + + @Test + void exitingModeWaitsForBothBusinessAndTidyWorkToDrain() { + TidyModeSnapshot exiting = snapshot(false, TidyEffectiveState.EXITING_TIDY, 30); + when(mapper.selectTidyModeForUpdate("01")).thenReturn(exiting); + when(mapper.countActiveBusinessExecution("01")).thenReturn(1); + when(mapper.countActiveManualTidy("01")).thenReturn(0); + + TidyModeSnapshot reconciled = service.reconcile("01"); + + assertThat(reconciled.effectiveState()).isEqualTo(TidyEffectiveState.EXITING_TIDY); + assertThat(reconciled.drainCount()).isEqualTo(1); + verify(mapper, never()).setTidyModeRequest(anyString(), anyBoolean(), anyString(), + anyString(), anyString(), anyLong()); + } + + private TidyModeSnapshot snapshot(boolean requested, TidyEffectiveState state, long version) { + return new TidyModeSnapshot("01", requested, state, 0, 0, "TEST", version, + "tester", LocalDateTime.of(2026, 7, 22, 10, 0)); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidySchedulerTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidySchedulerTest.java new file mode 100644 index 0000000..04dfd93 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidySchedulerTest.java @@ -0,0 +1,185 @@ +package com.ruoyi.algorithm.wms.tidy; + +import com.ruoyi.algorithm.integration.AlgorithmProperties; +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.integration.SchedulingMode; +import com.ruoyi.algorithm.tidy.TidyCandidate; +import com.ruoyi.algorithm.tidy.TidyCandidateType; +import com.ruoyi.algorithm.tidy.TidyMove; +import com.ruoyi.algorithm.tidy.TidyPlan; +import com.ruoyi.algorithm.wms.WmsAlgorithmMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +class TidySchedulerTest { + private TidyModeService mode; + private ExecutionAdmissionService admission; + private WmsAlgorithmMapper mapper; + private SchedulingFacade facade; + private TidyWorkflowStarter starter; + private TidyScheduler scheduler; + + @BeforeEach + void setUp() { + mode = mock(TidyModeService.class); + admission = mock(ExecutionAdmissionService.class); + mapper = mock(WmsAlgorithmMapper.class); + facade = mock(SchedulingFacade.class); + starter = mock(TidyWorkflowStarter.class); + AlgorithmProperties properties = new AlgorithmProperties(); + properties.setMode(SchedulingMode.ACTIVE); + scheduler = new TidyScheduler(mode, admission, mapper, facade, starter, properties); + when(mode.status("01")).thenReturn(snapshot(TidyEffectiveState.NORMAL)); + when(facade.planTidy(eq("01"), any(Instant.class))) + .thenReturn(new TidyPlan(List.of(), List.of())); + } + + @Test + void nonNormalModeDoesNothing() { + when(mode.status("01")).thenReturn(snapshot(TidyEffectiveState.TIDY_ACTIVE)); + scheduler.scanAutomatic(); + verifyNoInteractions(admission, facade, starter); + verify(mapper, never()).claimTidyLane(any(), any(), any(Integer.class)); + } + + @Test + void activeBusinessOrExistingAutomaticTidyPreventsClaim() { + when(mapper.countActiveBusinessExecution("01")).thenReturn(1); + scheduler.scanAutomatic(); + verify(mapper, never()).claimTidyLane(any(), any(), any(Integer.class)); + + when(mapper.countActiveBusinessExecution("01")).thenReturn(0); + when(mapper.countActiveAutomaticTidy()).thenReturn(1); + scheduler.scanAutomatic(); + verify(mapper, never()).claimTidyLane(any(), any(), any(Integer.class)); + } + + @Test + void noClaimDoesNotPlanOrStart() { + scheduler.scanAutomatic(); + verify(admission).assertAllowed("01", ExecutionWorkType.AUTO_TIDY); + verify(facade).planTidy(eq("01"), any(Instant.class)); + verifyNoInteractions(starter); + } + + @Test + void admissionLockIsAcquiredBeforeBusinessCountsAreRead() { + scheduler.scanAutomatic(); + + var ordered = inOrder(admission, mapper); + ordered.verify(admission).assertAllowed("01", ExecutionWorkType.AUTO_TIDY); + ordered.verify(mapper).countActiveBusinessExecution("01"); + ordered.verify(mapper).countActiveAutomaticTidy(); + } + + @Test + void safeCandidateForClaimedLaneStartsExactlyOnce() { + TidyLaneClaim claim = claim(); + TidyCandidate candidate = candidate(); + when(facade.planTidy(eq("01"), any(Instant.class))).thenReturn(new TidyPlan(List.of(candidate), List.of())); + when(mapper.selectLaneCodeForSpace("01", "SPACE-A")).thenReturn("LANE-1"); + when(mapper.claimTidyLaneFromCandidates("01", "LANE-1", "tidy-scheduler", 60)).thenReturn(claim); + + scheduler.scanAutomatic(); + + verify(starter).startAutomatic(claim, candidate); + verify(mapper, never()).claimTidyLane(any(), any(), any(Integer.class)); + verify(mapper, never()).releaseTidyLane(any(), any(), any(), any(Long.class), any(Boolean.class), any()); + } + + @Test + void noCandidateForClaimedLaneCompletesCurrentVersionWithoutStarting() { + TidyLaneClaim claim = claim(); + when(mapper.claimTidyLane("01", "tidy-scheduler", 60)).thenReturn(claim).thenReturn(null); + when(facade.planTidy(eq("01"), any(Instant.class))) + .thenReturn(new TidyPlan(List.of(candidate()), List.of())); + when(mapper.selectLaneCodeForSpace("01", "SPACE-A")).thenReturn("OTHER-LANE"); + + scheduler.scanAutomatic(); + + verifyNoInteractions(starter); + verify(mapper).releaseTidyLane("01", "LANE-1", claim.claimToken(), 4, + true, "NO_SAFE_CANDIDATE"); + } + + @Test + void claimsAPlannedLaneDirectlyWithoutWalkingTheQueue() { + TidyLaneClaim matchingClaim = claim("LANE-2"); + TidyCandidate candidate = candidate(); + when(facade.planTidy(eq("01"), any(Instant.class))) + .thenReturn(new TidyPlan(List.of(candidate), List.of())); + when(mapper.selectLaneCodeForSpace("01", "SPACE-A")).thenReturn("LANE-2"); + when(mapper.claimTidyLaneFromCandidates("01", "LANE-2", "tidy-scheduler", 60)) + .thenReturn(matchingClaim); + + scheduler.scanAutomatic(); + + verify(mapper).claimTidyLaneFromCandidates("01", "LANE-2", "tidy-scheduler", 60); + verify(mapper, never()).claimTidyLane(any(), any(), any(Integer.class)); + verify(starter).startAutomatic(matchingClaim, candidate); + verify(mapper, never()).releaseTidyLane(eq("01"), any(), any(), any(Long.class), + any(Boolean.class), any()); + } + + @Test + void plansBeforeTakingTheAdmissionLock() { + TidyCandidate candidate = candidate(); + when(facade.planTidy(eq("01"), any(Instant.class))) + .thenReturn(new TidyPlan(List.of(candidate), List.of())); + when(mapper.selectLaneCodeForSpace("01", "SPACE-A")).thenReturn("LANE-1"); + + scheduler.scanAutomatic(); + + var ordered = inOrder(facade, admission); + ordered.verify(facade).planTidy(eq("01"), any(Instant.class)); + ordered.verify(admission).assertAllowed("01", ExecutionWorkType.AUTO_TIDY); + } + + @Test + void startFailureRequeuesClaimedVersion() { + TidyLaneClaim claim = claim(); + TidyCandidate candidate = candidate(); + when(facade.planTidy(eq("01"), any(Instant.class))).thenReturn(new TidyPlan(List.of(candidate), List.of())); + when(mapper.selectLaneCodeForSpace("01", "SPACE-A")).thenReturn("LANE-1"); + when(mapper.claimTidyLaneFromCandidates("01", "LANE-1", "tidy-scheduler", 60)).thenReturn(claim); + when(starter.startAutomatic(claim, candidate)).thenThrow(new IllegalStateException("STALE_CANDIDATE")); + + scheduler.scanAutomatic(); + + verify(mapper).releaseTidyLane("01", "LANE-1", claim.claimToken(), 4, + false, "STALE_CANDIDATE"); + } + + private TidyModeSnapshot snapshot(TidyEffectiveState state) { + return new TidyModeSnapshot("01", state != TidyEffectiveState.NORMAL, state, + 0, 0, "TEST", 1, "tester", LocalDateTime.now()); + } + + private TidyLaneClaim claim() { + return claim("LANE-1"); + } + + private TidyLaneClaim claim(String laneCode) { + return new TidyLaneClaim("01", laneCode, 4, UUID.randomUUID(), Instant.now().plusSeconds(600)); + } + + private TidyCandidate candidate() { + return new TidyCandidate(TidyCandidateType.CONSOLIDATE_INCUBATION, "P-1", + List.of(new TidyMove("TRAY-1", "SPACE-A", "SPACE-B")), Optional.empty(), "test"); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyVehicleCapacityTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyVehicleCapacityTest.java new file mode 100644 index 0000000..92b0bc7 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyVehicleCapacityTest.java @@ -0,0 +1,32 @@ +package com.ruoyi.algorithm.wms.tidy; + +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class TidyVehicleCapacityTest { + @Test + void countsOnlyHealthyOnlineIdleVehiclesAndLeavesRunningWorkInCapacity() { + VehicleSnapshot healthyIdle = new VehicleSnapshot("1", true, true, true, null); + VehicleSnapshot healthyTidy = new VehicleSnapshot("2", true, true, false, "MANUAL_TIDY"); + VehicleSnapshot busyInbound = new VehicleSnapshot("3", true, true, false, "INBOUND"); + + TidyVehicleCapacity.CapacityResult result = new TidyVehicleCapacity().calculate( + List.of(healthyIdle, healthyTidy, busyInbound), 1, Set.of("2")); + + assertThat(result.effectiveCapacity()).isEqualTo(1); + assertThat(result.newSlots()).isEqualTo(0); + } + + @Test + void offlineOrAlarmedAssignedVehicleCannotConsumeNewCapacity() { + TidyVehicleCapacity.CapacityResult result = new TidyVehicleCapacity().calculate( + List.of(new VehicleSnapshot("1", false, false, false, "MANUAL_TIDY"), + new VehicleSnapshot("2", true, true, true, null)), 0, Set.of("1")); + assertThat(result.effectiveCapacity()).isEqualTo(1); + assertThat(result.newSlots()).isEqualTo(1); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyWorkflowCoordinatorTest.java b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyWorkflowCoordinatorTest.java new file mode 100644 index 0000000..1a7bd21 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/algorithm/wms/tidy/TidyWorkflowCoordinatorTest.java @@ -0,0 +1,32 @@ +package com.ruoyi.algorithm.wms.tidy; + +import com.ruoyi.algorithm.tidy.TidyCandidate; +import com.ruoyi.algorithm.tidy.TidyCandidateType; +import com.ruoyi.algorithm.tidy.TidyMove; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class TidyWorkflowCoordinatorTest { + @Test + void delegatesAutomaticStartAndCallbacks() { + TidyWorkflowTransaction transaction = mock(TidyWorkflowTransaction.class); + TidyWorkflowCoordinator coordinator = new TidyWorkflowCoordinator(transaction); + TidyLaneClaim claim = new TidyLaneClaim("01", "L1", 1, UUID.randomUUID(), + java.time.Instant.now().plusSeconds(30)); + TidyCandidate candidate = new TidyCandidate(TidyCandidateType.GUEST_RETURN, "P", + List.of(new TidyMove("T", "A", "B")), Optional.empty(), "test"); + UUID workflow = UUID.randomUUID(); + when(transaction.startAutomatic(claim, candidate)).thenReturn(workflow); + when(transaction.onJobFinished("J", "FINISHED")).thenReturn(true); + + assertThat(coordinator.start(TidyOrigin.AUTO_TIDY, "01", candidate)).isNull(); + assertThat(transaction.onJobFinished("J", "FINISHED")).isTrue(); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/api/service/ToWmsServiceImplInboundIdempotencyTest.java b/ruoyi-admin/src/test/java/com/ruoyi/api/service/ToWmsServiceImplInboundIdempotencyTest.java new file mode 100644 index 0000000..f3457e5 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/api/service/ToWmsServiceImplInboundIdempotencyTest.java @@ -0,0 +1,38 @@ +package com.ruoyi.api.service; + +import com.ruoyi.api.domain.WmsJobRequest; +import com.ruoyi.api.service.impl.ToWmsServiceImpl; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.job.mydojob.service.IMydoJobService; +import com.ruoyi.job.mydojobfinish.service.IMydoJobFinishService; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class ToWmsServiceImplInboundIdempotencyTest { + @Test + void repeatedInboundCompletionReturnsSuccessWhenJobAlreadyMovedToFinishTable() { + IMydoJobService activeJobs = mock(IMydoJobService.class); + IMydoJobFinishService finishedJobs = mock(IMydoJobFinishService.class); + when(activeJobs.selectMydoJobListApi(org.mockito.ArgumentMatchers.any())).thenReturn(List.of()); + when(finishedJobs.selectMydoJobFinishByJobId("JOB-1")).thenReturn(new com.ruoyi.job.mydojobfinish.domain.MydoJobFinish()); + + ToWmsServiceImpl service = new ToWmsServiceImpl(); + ReflectionTestUtils.setField(service, "mydoJobService", activeJobs); + ReflectionTestUtils.setField(service, "mydoJobFinishService", finishedJobs); + + WmsJobRequest request = new WmsJobRequest(); + request.setWmsType("1"); + request.setJobId("JOB-1"); + request.setTaskNo("TASK-1"); + + AjaxResult result = service.jobFinish(request); + + assertThat(result.isSuccess()).isTrue(); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplEntranceClaimTest.java b/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplEntranceClaimTest.java new file mode 100644 index 0000000..4696df5 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplEntranceClaimTest.java @@ -0,0 +1,53 @@ +package com.ruoyi.api.service.impl; + +import com.ruoyi.api.domain.RequestEnter; +import com.ruoyi.bas.BasProduct.domain.BasProduct; +import com.ruoyi.bas.BasProduct.service.IBasProductService; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.job.mydojob.domain.MydoJob; +import com.ruoyi.job.mydojob.service.IMydoJobService; +import com.ruoyi.job.mydojobdetail.domain.MydoJobDetail; +import com.ruoyi.job.mydojobdetail.service.IMydoJobDetailService; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class ToWmsServiceImplEntranceClaimTest { + @Test + void missingProductTraySizeUsesTheDefaultSizeZero() { + IMydoJobService jobs = mock(IMydoJobService.class); + IMydoJobDetailService details = mock(IMydoJobDetailService.class); + IBasProductService products = mock(IBasProductService.class); + ToWmsServiceImpl service = new ToWmsServiceImpl(); + ReflectionTestUtils.setField(service, "mydoJobService", jobs); + ReflectionTestUtils.setField(service, "mydoJobDetailService", details); + ReflectionTestUtils.setField(service, "basProductService", products); + + MydoJob job = new MydoJob(); + job.setJobId("JOB-1"); + job.setTaskNo("TASK-1"); + job.setTrayCode("TRAY-1"); + when(jobs.selectMydoJobByEntranceId(org.mockito.ArgumentMatchers.any())).thenReturn(job); + + MydoJobDetail detail = new MydoJobDetail(); + detail.setProductId("PRODUCT-1"); + when(details.selectMydoJobDetailListByJobId("JOB-1")).thenReturn(List.of(detail)); + when(products.selectBasProductByProductId("PRODUCT-1")).thenReturn(new BasProduct()); + + RequestEnter request = new RequestEnter(); + request.setEntranceId("L1004"); + request.setSize("0"); + + AjaxResult result = service.selectMydoJobByEntranceId(request); + + assertThat(result.isSuccess()).isTrue(); + assertThat(result.get(AjaxResult.DATA_TAG)).isInstanceOf(java.util.Map.class); + verify(jobs).updateMydoJob(job); + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplInboundTest.java b/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplInboundTest.java new file mode 100644 index 0000000..bb62389 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplInboundTest.java @@ -0,0 +1,117 @@ +package com.ruoyi.api.service.impl; + +import com.ruoyi.algorithm.wms.InboundAllocationResult; +import com.ruoyi.algorithm.wms.WmsInboundAllocationService; +import com.ruoyi.api.domain.RequestEnter; +import com.ruoyi.api.domain.ReMaterialParam; +import com.ruoyi.api.domain.RequestEnterResponse; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.job.mydojob.domain.MydoJob; +import com.ruoyi.job.mydojob.mapper.MydoJobMapper; +import com.ruoyi.job.mydojob.service.IMydoJobService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class ToWmsServiceImplInboundTest { + private MydoJobMapper jobMapper; + private WmsInboundAllocationService allocationService; + private ToWmsServiceImpl service; + private RequestEnter request; + private MydoJob job; + + @BeforeEach + void setUp() { + jobMapper = mock(MydoJobMapper.class); + allocationService = mock(WmsInboundAllocationService.class); + service = new ToWmsServiceImpl(); + ReflectionTestUtils.setField(service, "mydoJobMapper", jobMapper); + ReflectionTestUtils.setField(service, "inboundAllocationService", allocationService); + + request = new RequestEnter(); + request.setTaskNo("T-1"); + request.setDeviceCode("D-1"); + + job = new MydoJob(); + job.setJobId("J-1"); + job.setTaskNo("T-1"); + job.setTrayCode("TRAY-1"); + job.setInOrOut("1"); + when(jobMapper.selectInJobByTaskNo("T-1")).thenReturn(job); + } + + @Test + void delegatesUnassignedInboundJobToAlgorithmRouter() { + MydoJob allocated = copyWithSpace("SPACE-1"); + when(allocationService.allocate(job, "D-1")) + .thenReturn(InboundAllocationResult.success(allocated)); + + AjaxResult result = service.requestEnterByTaskNo(request); + + assertThat(result.isSuccess()).isTrue(); + assertThat(result.get(AjaxResult.DATA_TAG)).isSameAs(allocated); + verify(allocationService).allocate(job, "D-1"); + verify(jobMapper, never()).allotInJobSpace(org.mockito.ArgumentMatchers.any()); + } + + @Test + void returnsAlgorithmRejectionReasonWithoutExecutingAnotherAllocator() { + when(allocationService.allocate(job, "D-1")) + .thenReturn(InboundAllocationResult.failure("NO_FEASIBLE_LOCATION", "no legal space")); + + AjaxResult result = service.requestEnterByTaskNo(request); + + assertThat(result.isError()).isTrue(); + assertThat(result.get(AjaxResult.MSG_TAG)).isEqualTo("no legal space"); + assertThat(result.get("algorithmCode")).isEqualTo("NO_FEASIBLE_LOCATION"); + verify(jobMapper, never()).allotInJobSpace(org.mockito.ArgumentMatchers.any()); + } + + @Test + void keepsExistingAssignmentWithoutPlanningAgain() { + job.setCargoSpaceId("SPACE-EXISTING"); + + AjaxResult result = service.requestEnterByTaskNo(request); + + assertThat(result.isSuccess()).isTrue(); + assertThat(result.get(AjaxResult.DATA_TAG)).isSameAs(job); + verify(allocationService, never()).allocate(org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any()); + } + + @Test + void reassignUsesTheSameAlgorithmRouterAndReturnsTheNewSpace() { + IMydoJobService jobService = mock(IMydoJobService.class); + ReflectionTestUtils.setField(service, "mydoJobService", jobService); + job.setCargoSpaceId("OLD-SPACE"); + job.setEntranceId("PORT-1"); + when(jobService.selectMydoJobByJobId("J-1")).thenReturn(job); + MydoJob allocated = copyWithSpace("NEW-SPACE"); + when(allocationService.reallocate(job, "PORT-1")) + .thenReturn(InboundAllocationResult.success(allocated)); + + AjaxResult result = service.reAssign(new ReMaterialParam("J-1")); + + assertThat(result.isSuccess()).isTrue(); + assertThat(result.get(AjaxResult.DATA_TAG)).isInstanceOf(RequestEnterResponse.class); + assertThat(((RequestEnterResponse) result.get(AjaxResult.DATA_TAG)).getCargoSpaceId()) + .isEqualTo("NEW-SPACE"); + verify(allocationService).reallocate(job, "PORT-1"); + } + + private MydoJob copyWithSpace(String spaceId) { + MydoJob allocated = new MydoJob(); + allocated.setJobId(job.getJobId()); + allocated.setTaskNo(job.getTaskNo()); + allocated.setTrayCode(job.getTrayCode()); + allocated.setInOrOut(job.getInOrOut()); + allocated.setCargoSpaceId(spaceId); + return allocated; + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplWorkflowCallbackTest.java b/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplWorkflowCallbackTest.java new file mode 100644 index 0000000..4cef060 --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/api/service/impl/ToWmsServiceImplWorkflowCallbackTest.java @@ -0,0 +1,166 @@ +package com.ruoyi.api.service.impl; + +import com.ruoyi.algorithm.wms.OutboundWorkflowCoordinator; +import com.ruoyi.algorithm.wms.InboundAllocationTransaction; +import com.ruoyi.algorithm.wms.WmsAlgorithmMapper; +import com.ruoyi.algorithm.wms.WmsInboundAllocationService; +import com.ruoyi.algorithm.integration.SchedulingFacade; +import com.ruoyi.algorithm.integration.SchedulingMode; +import com.ruoyi.algorithm.integration.SchedulingRoutingPolicy; +import com.ruoyi.algorithm.repository.ReservationResult; +import com.ruoyi.api.domain.WmsJobRequest; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.job.mydojob.domain.MydoJob; +import com.ruoyi.job.mydojob.mapper.MydoJobMapper; +import com.ruoyi.job.mydojob.service.IMydoJobService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.transaction.annotation.Transactional; + +import java.lang.reflect.Method; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class ToWmsServiceImplWorkflowCallbackTest { + private IMydoJobService jobService; + private SchedulingFacade facade; + private OutboundWorkflowCoordinator workflowCoordinator; + private ToWmsServiceImpl service; + + @BeforeEach + void setUp() { + jobService = mock(IMydoJobService.class); + facade = mock(SchedulingFacade.class); + workflowCoordinator = mock(OutboundWorkflowCoordinator.class); + service = new ToWmsServiceImpl(); + ReflectionTestUtils.setField(service, "mydoJobService", jobService); + ReflectionTestUtils.setField(service, "inboundAllocationService", new WmsInboundAllocationService( + facade, mock(WmsAlgorithmMapper.class), mock(MydoJobMapper.class), + mock(InboundAllocationTransaction.class))); + ReflectionTestUtils.setField(service, "outboundWorkflowCoordinator", workflowCoordinator); + } + + @Test + void inboundCompletionReleasesActiveReservationOnlyAfterLegacyCompletion() { + MydoJob job = job("IN-JOB", "IN-TASK"); + job.setWarehouseId("01"); + when(jobService.selectMydoJobListApi(org.mockito.ArgumentMatchers.any(MydoJob.class))) + .thenReturn(List.of(job)); + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false)); + when(facade.releaseInboundReservation(org.mockito.ArgumentMatchers.eq("01"), anyString())) + .thenAnswer(invocation -> ReservationResult.released(invocation.getArgument(1))); + WmsJobRequest request = request("1", "IN-TASK"); + request.setJobId("IN-JOB"); + + AjaxResult result = service.jobFinish(request); + + assertThat(result.isSuccess()).isTrue(); + org.mockito.InOrder order = inOrder(jobService, facade); + order.verify(jobService).selectMydoJobListApi(org.mockito.ArgumentMatchers.any(MydoJob.class)); + order.verify(jobService).manualCompleted(job, 1); + order.verify(facade).routingPolicy(); + order.verify(facade).releaseInboundReservation(org.mockito.ArgumentMatchers.eq("01"), anyString()); + } + + @Test + void inboundCompletionFailsWhenActiveReservationCannotBeReleased() { + MydoJob job = job("IN-JOB", "IN-TASK"); + job.setWarehouseId("01"); + when(jobService.selectMydoJobListApi(org.mockito.ArgumentMatchers.any(MydoJob.class))) + .thenReturn(List.of(job)); + when(facade.routingPolicy()).thenReturn(new SchedulingRoutingPolicy(SchedulingMode.ACTIVE, false)); + when(facade.releaseInboundReservation(org.mockito.ArgumentMatchers.eq("01"), anyString())) + .thenAnswer(invocation -> ReservationResult.conflict("LOCK_TIMEOUT", invocation.getArgument(1))); + WmsJobRequest request = request("1", "IN-TASK"); + request.setJobId("IN-JOB"); + + assertThatThrownBy(() -> service.jobFinish(request)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("reservation"); + } + + @Test + void moveCompletionAdvancesWorkflowOnlyAfterLegacyCompletion() { + MydoJob job = job("MOVE-JOB", "MOVE-TASK"); + when(jobService.selectMydoJobListApi(org.mockito.ArgumentMatchers.any(MydoJob.class))) + .thenReturn(List.of(job)); + + AjaxResult result = service.jobFinish(request("7", "MOVE-TASK")); + + assertThat(result.isSuccess()).isTrue(); + org.mockito.InOrder order = inOrder(jobService, workflowCoordinator); + order.verify(jobService).selectMydoJobListApi(org.mockito.ArgumentMatchers.any(MydoJob.class)); + order.verify(jobService).ykCompleted(job); + order.verify(workflowCoordinator).onJobFinished("MOVE-JOB"); + } + + @Test + void outboundCompletionAdvancesWorkflowOnlyAfterExecutionPhaseUpdate() { + MydoJob job = job("OUT-JOB", "OUT-TASK"); + when(jobService.selectMydoJobListApi(org.mockito.ArgumentMatchers.any(MydoJob.class))) + .thenReturn(List.of(job)); + + AjaxResult result = service.jobFinish(request("2", "OUT-TASK")); + + assertThat(result.isSuccess()).isTrue(); + assertThat(job.getExecutionPhase()).isEqualTo("2"); + org.mockito.InOrder order = inOrder(jobService, workflowCoordinator); + order.verify(jobService).selectMydoJobListApi(org.mockito.ArgumentMatchers.any(MydoJob.class)); + order.verify(jobService).updateMydoJob(job); + order.verify(workflowCoordinator).onJobFinished("OUT-JOB"); + } + + @Test + void missingJobReturnsExistingErrorWithoutAdvancingWorkflow() { + when(jobService.selectMydoJobListApi(org.mockito.ArgumentMatchers.any(MydoJob.class))) + .thenReturn(List.of()); + + AjaxResult result = service.jobFinish(request("7", "MISSING-TASK")); + + assertThat(result.isError()).isTrue(); + assertThat(result.get(AjaxResult.MSG_TAG)).isEqualTo("任务不存在"); + verify(workflowCoordinator, never()).onJobFinished(org.mockito.ArgumentMatchers.anyString()); + } + + @Test + void invalidWmsTypeDoesNotAdvanceWorkflow() { + AjaxResult result = service.jobFinish(request("99", "UNKNOWN-TASK")); + + assertThat(result.isError()).isTrue(); + verify(workflowCoordinator, never()).onJobFinished(org.mockito.ArgumentMatchers.anyString()); + } + + @Test + void jobFinishIsTransactional() throws NoSuchMethodException { + Method method = ToWmsServiceImpl.class.getMethod("jobFinish", WmsJobRequest.class); + + Transactional transactional = method.getAnnotation(Transactional.class); + + assertThat(transactional).isNotNull(); + assertThat(transactional.rollbackFor()).contains(Exception.class); + } + + private WmsJobRequest request(String wmsType, String taskNo) { + WmsJobRequest request = new WmsJobRequest(); + request.setWmsType(wmsType); + request.setTaskNo(taskNo); + return request; + } + + private MydoJob job(String jobId, String taskNo) { + MydoJob job = new MydoJob(); + job.setJobId(jobId); + job.setTaskNo(taskNo); + return job; + } + +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/job/mydojob/service/impl/MydoJobServiceImplMoveCompletionTest.java b/ruoyi-admin/src/test/java/com/ruoyi/job/mydojob/service/impl/MydoJobServiceImplMoveCompletionTest.java new file mode 100644 index 0000000..015573c --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/job/mydojob/service/impl/MydoJobServiceImplMoveCompletionTest.java @@ -0,0 +1,70 @@ +package com.ruoyi.job.mydojob.service.impl; + +import com.ruoyi.job.mydojob.domain.MydoJob; +import com.ruoyi.job.mydojob.mapper.MydoJobMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.stubbing.Answer; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.HashMap; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +class MydoJobServiceImplMoveCompletionTest { + private MydoJobMapper mapper; + private MydoJobServiceImpl service; + + @BeforeEach + void setUp() { + mapper = mock(MydoJobMapper.class); + service = new MydoJobServiceImpl(); + ReflectionTestUtils.setField(service, "mydoJobMapper", mapper); + } + + @Test + void algorithmMoveUsesAlgorithmOwnedCompletionProcedure() { + MydoJob job = job("ALG-MOVE", "28"); + completeSuccessfullyWhen(mapper, true); + + service.ykCompleted(job); + + verify(mapper).completeAlgorithmMove(any(HashMap.class)); + verify(mapper, never()).ykCompleted(any(HashMap.class)); + } + + @Test + void legacyMoveKeepsUsingLegacyCompletionProcedure() { + MydoJob job = job("LEGACY-MOVE", "30"); + completeSuccessfullyWhen(mapper, false); + + service.ykCompleted(job); + + verify(mapper).ykCompleted(any(HashMap.class)); + verify(mapper, never()).completeAlgorithmMove(any(HashMap.class)); + } + + private void completeSuccessfullyWhen(MydoJobMapper target, boolean algorithmMove) { + Answer answer = invocation -> { + HashMap parameters = invocation.getArgument(0); + parameters.put("v_result", 10); + return null; + }; + if (algorithmMove) { + doAnswer(answer).when(target).completeAlgorithmMove(any(HashMap.class)); + } else { + doAnswer(answer).when(target).ykCompleted(any(HashMap.class)); + } + } + + private MydoJob job(String jobId, String inOrOut) { + MydoJob job = new MydoJob(); + job.setJobId(jobId); + job.setInOrOut(inOrOut); + return job; + } +} diff --git a/ruoyi-admin/src/test/java/com/ruoyi/job/mydojobfinish/MydoJobFinishMapperSqlTest.java b/ruoyi-admin/src/test/java/com/ruoyi/job/mydojobfinish/MydoJobFinishMapperSqlTest.java new file mode 100644 index 0000000..0eaca3a --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/job/mydojobfinish/MydoJobFinishMapperSqlTest.java @@ -0,0 +1,31 @@ +package com.ruoyi.job.mydojobfinish; + +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; + +class MydoJobFinishMapperSqlTest { + @Test + void historyQueriesAndActivityProjectionUseTheirDeclaredDomainTypes() throws IOException { + String xml = mapperXml(); + + assertThat(xml) + .contains("") + .contains("") + .contains("") + .contains(" + + + and license_code = #{licenseCode} + and start_time = #{startTime} + and expire_time = #{expireTime} + and status = #{status} + + order by create_time desc + + + + + + + + insert into sys_license + + license_code, + start_time, + expire_time, + status, + active_time, + active_by, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{licenseCode}, + #{startTime}, + #{expireTime}, + #{status}, + #{activeTime}, + #{activeBy}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + update sys_license + + license_code = #{licenseCode}, + start_time = #{startTime}, + expire_time = #{expireTime}, + status = #{status}, + active_time = #{activeTime}, + active_by = #{activeBy}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where license_id = #{licenseId} + + + + delete from sys_license where license_id = #{licenseId} + + + + delete from sys_license where license_id in + + #{licenseId} + + + + diff --git a/ruoyi-ui/.env.development b/ruoyi-ui/.env.development index a8531ba..bae6a96 100644 --- a/ruoyi-ui/.env.development +++ b/ruoyi-ui/.env.development @@ -1,5 +1,5 @@ # 页面标题 -VUE_APP_TITLE = "ForTucky WMS system" +VUE_APP_TITLE = "艾度 WMS system" # 开发环境配置 ENV = 'development' diff --git a/ruoyi-ui/.env.production b/ruoyi-ui/.env.production index 8074604..061cea2 100644 --- a/ruoyi-ui/.env.production +++ b/ruoyi-ui/.env.production @@ -1,5 +1,5 @@ # 页面标题 -VUE_APP_TITLE = "ForTucky WMS system" +VUE_APP_TITLE = "艾度 WMS system" # 生产环境配置 ENV = 'production' diff --git a/ruoyi-ui/.env.staging b/ruoyi-ui/.env.staging index dbe8edd..ae39ce6 100644 --- a/ruoyi-ui/.env.staging +++ b/ruoyi-ui/.env.staging @@ -1,5 +1,5 @@ # 页面标题 -VUE_APP_TITLE = "ForTucky WMS system" +VUE_APP_TITLE = "艾度 WMS system" BABEL_ENV = production diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json index c98ae7c..dee870a 100644 --- a/ruoyi-ui/package.json +++ b/ruoyi-ui/package.json @@ -44,6 +44,7 @@ "sortablejs": "1.10.2", "splitpanes": "2.4.1", "vue": "2.6.12", + "vue-barcode": "^1.3.0", "vue-count-to": "1.0.13", "vue-cropper": "0.5.5", "vue-easy-print": "^0.0.8", diff --git a/ruoyi-ui/src/api/agvPoint/point.js b/ruoyi-ui/src/api/agvPoint/point.js new file mode 100644 index 0000000..e7fb13f --- /dev/null +++ b/ruoyi-ui/src/api/agvPoint/point.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询agv站点管理列表 +export function listPoint(query) { + return request({ + url: '/bas/agvPoint/list', + method: 'get', + params: query + }) +} + +// 查询agv站点管理详细 +export function getPoint(id) { + return request({ + url: '/bas/agvPoint' + id, + method: 'get' + }) +} + +// 新增agv站点管理 +export function addPoint(data) { + return request({ + url: '/bas/agvPoint', + method: 'post', + data: data + }) +} + +// 修改agv站点管理 +export function updatePoint(data) { + return request({ + url: '/bas/agvPoint', + method: 'put', + data: data + }) +} + +// 删除agv站点管理 +export function delPoint(id) { + return request({ + url: '/bas/agvPoint' + id, + method: 'delete' + }) +} diff --git a/ruoyi-ui/src/api/algorithm/tidy.js b/ruoyi-ui/src/api/algorithm/tidy.js new file mode 100644 index 0000000..10dfba1 --- /dev/null +++ b/ruoyi-ui/src/api/algorithm/tidy.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +export function getTidyStatus() { + return request({ url: '/algorithm/tidy/status', method: 'get' }) +} + +export function setTidyMode(enabled) { + return request({ url: '/algorithm/tidy/mode', method: 'put', data: { enabled } }) +} diff --git a/ruoyi-ui/src/api/license.js b/ruoyi-ui/src/api/license.js new file mode 100644 index 0000000..2ec322f --- /dev/null +++ b/ruoyi-ui/src/api/license.js @@ -0,0 +1,40 @@ +import request from '@/utils/request' + +export function listLicense(query) { + return request({ + url: '/system/license/list', + method: 'get', + params: query + }) +} + +export function delLicense(ids) { + return request({ + url: '/system/license/remove', + method: 'post', + params: { ids } + }) +} + +export function activeLicense(licenseCode) { + return request({ + url: '/system/license/active', + method: 'post', + params: { licenseCode } + }) +} + +export function getLicenseInfo() { + return request({ + url: '/system/license/info', + method: 'get' + }) +} + +export function generateLicense(type, projectNo) { + return request({ + url: '/system/license/generate', + method: 'get', + params: { type, projectNo } + }) +} diff --git a/ruoyi-ui/src/api/requestInterface/log.js b/ruoyi-ui/src/api/requestInterface/log.js index 123dca1..39ba634 100644 --- a/ruoyi-ui/src/api/requestInterface/log.js +++ b/ruoyi-ui/src/api/requestInterface/log.js @@ -9,6 +9,30 @@ export function listLog(query) { }) } + +export function getMethod() { + return request({ + url: '/requestInterface/log/getMethod', + method: 'get' + + }) +} + +export function getSource() { + return request({ + url: '/requestInterface/log/getSource', + method: 'get' + + }) +} + +export function getTarget() { + return request({ + url: '/requestInterface/log/getTarget', + method: 'get' + + }) +} // 查询接口记录详细 export function getLog(requestId) { return request({ diff --git a/ruoyi-ui/src/api/stock/management.js b/ruoyi-ui/src/api/stock/management.js index a1873b6..3add5d7 100644 --- a/ruoyi-ui/src/api/stock/management.js +++ b/ruoyi-ui/src/api/stock/management.js @@ -10,10 +10,11 @@ export function listManagement(query) { } // 查询库存信息详细 -export function getManagement(stockId) { +export function getManagement(stockId, warehouseCode) { return request({ url: '/stock/management/' + stockId, - method: 'get' + method: 'get', + params: {"warehouseCode": warehouseCode} }) } @@ -45,12 +46,14 @@ export function updateManagement(data) { } // 删除库存信息 -export function delManagement(stockId) { +export function delManagement(stockId, warehouseCode) { return request({ url: '/stock/management/' + stockId, - method: 'delete' + method: 'delete', + params: {"warehouseCode": warehouseCode} }) } + //重置盘点记录 export function resetPdRecord() { return request({ diff --git a/ruoyi-ui/src/components/Pagination/index.vue b/ruoyi-ui/src/components/Pagination/index.vue index 08ac487..eda541b 100644 --- a/ruoyi-ui/src/components/Pagination/index.vue +++ b/ruoyi-ui/src/components/Pagination/index.vue @@ -36,7 +36,7 @@ export default { pageSizes: { type: Array, default() { - return [10, 20, 30, 50] + return [10, 50, 100, 1000] } }, // 移动端页码按钮的数量端默认值5 diff --git a/ruoyi-ui/src/layout/components/Navbar.vue b/ruoyi-ui/src/layout/components/Navbar.vue index 8b51fc4..a210626 100644 --- a/ruoyi-ui/src/layout/components/Navbar.vue +++ b/ruoyi-ui/src/layout/components/Navbar.vue @@ -5,6 +5,11 @@ +
+ + 系统授权将于 {{ licenseExpireText }} 后过期,请及时联系管理员续期 +
+