Commit 722a2e78 by wangchunyang

退库、统计相关功能,仓库、库位选择组件

parent 67fafb93
...@@ -77,3 +77,20 @@ export function Ship(data) { ...@@ -77,3 +77,20 @@ export function Ship(data) {
data: data data: data
}) })
} }
// 导出库存列表
export function exportInventory(query) {
return request({
url: '/inventory/inventory/export',
method: 'post',
params: query
})
}
// 查询库存明细列表(根据物料标识及检索条件)
export function listInventoryDetail(query) {
return request({
url: '/inventory/inventory/detailList',
method: 'get',
params: query
})
}
\ No newline at end of file
import request from '@/utils/request'
// 查询出入库统计列表
export function listInboundOutboundStatistics(query) {
return request({
url: '/inventory/statistics/inboundOutbound',
method: 'get',
params: query
})
}
// 导出出入库统计数据
export function exportInboundOutboundStatistics(query) {
return request({
url: '/inventory/statistics/inboundOutbound/export',
method: 'post',
params: query
})
}
...@@ -43,3 +43,12 @@ export function delLocations(id) { ...@@ -43,3 +43,12 @@ export function delLocations(id) {
method: 'delete' method: 'delete'
}) })
} }
// 查询库位列表(无权限限制,用于选择器)
export function listLocationsForSelector(query) {
return request({
url: '/inventory/locations/listForSelector',
method: 'get',
params: query
})
}
\ No newline at end of file
import request from '@/utils/request'
// 查询退库单明细列表
export function listReturnOrderItems(query) {
return request({
url: '/inventory/return_order_items/list',
method: 'get',
params: query
})
}
// 查询退库单明细详细
export function getReturnOrderItem(id) {
return request({
url: '/inventory/return_order_items/' + id,
method: 'get'
})
}
// 新增退库单明细
export function addReturnOrderItem(data) {
return request({
url: '/inventory/return_order_items',
method: 'post',
data: data
})
}
// 修改退库单明细
export function updateReturnOrderItem(data) {
return request({
url: '/inventory/return_order_items',
method: 'put',
data: data
})
}
// 删除退库单明细
export function delReturnOrderItem(id) {
return request({
url: '/inventory/return_order_items/' + id,
method: 'delete'
})
}
// 导出退库单明细
export function exportReturnOrderItems(query) {
return request({
url: '/inventory/return_order_items/export',
method: 'post',
params: query
})
}
import request from '@/utils/request'
// 查询退库单列表
export function listReturnOrders(query) {
return request({
url: '/inventory/return_orders/list',
method: 'get',
params: query
})
}
// 查询退库单详细
export function getReturnOrder(id) {
return request({
url: '/inventory/return_orders/' + id,
method: 'get'
})
}
// 新增退库单
export function addReturnOrder(data) {
return request({
url: '/inventory/return_orders',
method: 'post',
data: data
})
}
// 修改退库单
export function updateReturnOrder(data) {
return request({
url: '/inventory/return_orders',
method: 'put',
data: data
})
}
// 删除退库单
export function delReturnOrder(id) {
return request({
url: '/inventory/return_orders/' + id,
method: 'delete'
})
}
// 确认退库单
export function confirmReturnOrder(id) {
return request({
url: '/inventory/return_orders/confirm/' + id,
method: 'post'
})
}
...@@ -42,3 +42,12 @@ export function delWarehouses(id) { ...@@ -42,3 +42,12 @@ export function delWarehouses(id) {
method: 'delete' method: 'delete'
}) })
} }
// 查询仓库列表(无权限限制,用于选择器)
export function listWarehousesForSelector(query) {
return request({
url: '/inventory/warehouses/listForSelector',
method: 'get',
params: query
})
}
\ No newline at end of file
<template>
<el-dialog
:visible.sync="dialogVisible"
width="1000px"
append-to-body
class="location-selector-dialog"
:close-on-click-modal="false"
>
<span slot="title">
选择库位
<small class="title-tip">双击表格行可快速选择</small>
</span>
<div class="location-selector-body">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
label-width="90px"
class="location-selector-form"
>
<!-- <el-form-item label="库位编码" prop="locationCode">
<el-input
v-model="queryParams.locationCode"
placeholder="请输入库位编码"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item> -->
<el-form-item label="库位名称" prop="locationName">
<el-input
v-model="queryParams.locationName"
placeholder="请输入库位名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="仓库编码" prop="warehousesId">
<el-input
v-model="queryParams.warehousesId"
placeholder="请输入仓库编码"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item> -->
<!-- <el-form-item label="是否启用" prop="isEnabled">
<el-select
v-model="queryParams.isEnabled"
placeholder="请选择"
clearable
style="width: 180px"
>
<el-option label="是" value="1" />
<el-option label="否" value="0" />
</el-select>
</el-form-item> -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="loading"
:data="locationsList"
:max-height="380"
highlight-current-row
@current-change="handleCurrentChange"
@row-dblclick="handleRowDblClick"
style="flex: 1; min-height: 0;"
>
<el-table-column type="index" label="#" width="60" align="center" />
<!-- <el-table-column label="库位编码" prop="locationCode" width="150" /> -->
<el-table-column label="库位名称" prop="locationName" min-width="150" show-overflow-tooltip />
<el-table-column label="库位类型" prop="locationType" width="120" align="center">
<template slot-scope="scope">
<span v-if="scope.row.locationType === 1">货架</span>
<span v-else-if="scope.row.locationType === 2">地面</span>
<span v-else-if="scope.row.locationType === 3">货位</span>
<span v-else-if="scope.row.locationType === 4">专区</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="区域代码" prop="zoneCode" width="120" />
<!-- <el-table-column label="是否启用" prop="isEnabled" width="110" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.isEnabled === '1' || scope.row.isEnabled === 1 ? 'success' : 'info'" size="mini">
{{ scope.row.isEnabled === '1' || scope.row.isEnabled === 1 ? '是' : '否' }}
</el-tag>
</template>
</el-table-column> -->
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="close">取 消</el-button>
<el-button type="primary" @click="confirmSelection">确 定</el-button>
</div>
</el-dialog>
</template>
<script>
import { listLocationsForSelector } from "@/api/inventory/locations"
export default {
name: "LocationSelector",
props: {
value: {
type: Boolean,
default: false
},
warehousesId: {
type: String,
default: null
}
},
data() {
return {
locationsList: [],
loading: false,
total: 0,
currentLocation: null,
queryParams: {
pageNum: 1,
pageSize: 10,
locationCode: null,
locationName: null,
warehousesId: null,
isEnabled: "1"
}
}
},
computed: {
dialogVisible: {
get() {
return this.value
},
set(val) {
this.$emit("input", val)
}
}
},
watch: {
dialogVisible(val) {
if (val) {
this.$nextTick(() => {
this.init()
})
} else {
this.resetState()
}
},
warehousesId(val) {
if (val) {
this.queryParams.warehousesId = val
}
}
},
methods: {
init() {
// 如果传入了仓库编码,则自动设置查询条件
if (this.warehousesId) {
this.queryParams.warehousesId = this.warehousesId
}
if (this.locationsList.length === 0) {
this.getList()
} else {
// 如果仓库编码变化,重新查询
this.getList()
}
},
resetState() {
this.currentLocation = null
},
getList() {
this.loading = true
listLocationsForSelector(this.queryParams)
.then(res => {
this.locationsList = res.rows || []
this.total = res.total || 0
})
.finally(() => {
this.loading = false
})
},
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
resetQuery() {
this.queryParams = {
pageNum: 1,
pageSize: 10,
locationCode: null,
locationName: null,
isEnabled: "1",
warehousesId: this.warehousesId || null
}
// 如果传入了仓库编码,确保设置到查询参数中
if (this.warehousesId) {
this.queryParams.warehousesId = this.warehousesId
}
this.getList()
},
handleCurrentChange(row) {
this.currentLocation = row
},
handleRowDblClick(row) {
this.currentLocation = row
this.confirmSelection()
},
confirmSelection() {
if (!this.currentLocation) {
this.$message.warning("请先选择一个库位")
return
}
const payload = {
locationCode: this.currentLocation.locationCode,
locationName: this.currentLocation.locationName,
locationId: this.currentLocation.id,
warehousesId: this.currentLocation.warehousesId
}
this.$emit("selected", payload)
this.dialogVisible = false
},
close() {
this.dialogVisible = false
},
refresh() {
this.getList()
}
}
}
</script>
<style scoped>
.location-selector-dialog /deep/ .el-dialog__body {
padding: 10px 20px 0;
min-height: 500px;
display: flex;
flex-direction: column;
}
.location-selector-body {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
}
.location-selector-form {
margin-bottom: 10px;
}
.title-tip {
font-size: 12px;
color: #999;
margin-left: 8px;
}
</style>
<template>
<el-dialog
:visible.sync="dialogVisible"
width="900px"
append-to-body
class="owner-selector-dialog"
:close-on-click-modal="false"
>
<span slot="title">
选择货主
<small class="title-tip">双击表格行可快速选择</small>
</span>
<div class="owner-selector-body">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
label-width="90px"
class="owner-selector-form"
>
<el-form-item label="货主编码" prop="ownerCode">
<el-input
v-model="queryParams.ownerCode"
placeholder="请输入货主编码"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="货主名称" prop="ownerName">
<el-input
v-model="queryParams.ownerName"
placeholder="请输入货主名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="是否激活" prop="isActive">
<el-select
v-model="queryParams.isActive"
placeholder="请选择"
clearable
style="width: 180px"
>
<el-option label="是" value="1" />
<el-option label="否" value="0" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="loading"
:data="ownersList"
:max-height="380"
highlight-current-row
@current-change="handleCurrentChange"
@row-dblclick="handleRowDblClick"
style="flex: 1; min-height: 0;"
>
<el-table-column type="index" label="#" width="60" align="center" />
<el-table-column label="货主编码" prop="ownerCode" width="150" />
<el-table-column label="货主名称" prop="ownerName" min-width="220" show-overflow-tooltip />
<el-table-column label="联系人" prop="contactPerson" width="150" />
<el-table-column label="联系电话" prop="contactPhone" width="150" />
<el-table-column label="是否激活" prop="isActive" width="110" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.isActive === '1' || scope.row.isActive === 1 ? 'success' : 'info'" size="mini">
{{ scope.row.isActive === '1' || scope.row.isActive === 1 ? '是' : '否' }}
</el-tag>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="close">取 消</el-button>
<el-button type="primary" @click="confirmSelection">确 定</el-button>
</div>
</el-dialog>
</template>
<script>
import { listOwners } from "@/api/inventory/owners"
export default {
name: "OwnerSelector",
props: {
value: {
type: Boolean,
default: false
}
},
data() {
return {
ownersList: [],
loading: false,
total: 0,
currentOwner: null,
queryParams: {
pageNum: 1,
pageSize: 10,
ownerCode: null,
ownerName: null,
isActive: "1"
}
}
},
computed: {
dialogVisible: {
get() {
return this.value
},
set(val) {
this.$emit("input", val)
}
}
},
watch: {
dialogVisible(val) {
if (val) {
this.$nextTick(() => {
this.init()
})
} else {
this.resetState()
}
}
},
methods: {
init() {
if (this.ownersList.length === 0) {
this.getList()
}
},
resetState() {
this.currentOwner = null
},
getList() {
this.loading = true
listOwners(this.queryParams)
.then(res => {
this.ownersList = res.rows || []
this.total = res.total || 0
})
.finally(() => {
this.loading = false
})
},
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
resetQuery() {
this.queryParams = {
pageNum: 1,
pageSize: 10,
ownerCode: null,
ownerName: null,
isActive: "1"
}
this.getList()
},
handleCurrentChange(row) {
this.currentOwner = row
},
handleRowDblClick(row) {
this.currentOwner = row
this.confirmSelection()
},
confirmSelection() {
if (!this.currentOwner) {
this.$message.warning("请先选择一个货主")
return
}
const payload = {
ownerCode: this.currentOwner.ownerCode,
ownerName: this.currentOwner.ownerName,
ownerId: this.currentOwner.id
}
this.$emit("selected", payload)
this.dialogVisible = false
},
close() {
this.dialogVisible = false
},
refresh() {
this.getList()
}
}
}
</script>
<style scoped>
.owner-selector-dialog /deep/ .el-dialog__body {
padding: 10px 20px 0;
min-height: 500px;
display: flex;
flex-direction: column;
}
.owner-selector-body {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
}
.owner-selector-form {
margin-bottom: 10px;
}
.title-tip {
font-size: 12px;
color: #999;
margin-left: 8px;
}
</style>
<template>
<el-dialog
:visible.sync="dialogVisible"
width="900px"
append-to-body
class="warehouse-selector-dialog"
:close-on-click-modal="false"
>
<span slot="title">
选择仓库
<small class="title-tip">双击表格行可快速选择</small>
</span>
<div class="warehouse-selector-body">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
label-width="90px"
class="warehouse-selector-form"
>
<!-- <el-form-item label="仓库编码" prop="warehousesCode">
<el-input
v-model="queryParams.warehousesCode"
placeholder="请输入仓库编码"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item> -->
<el-form-item label="仓库名称" prop="warehousesName">
<el-input
v-model="queryParams.warehousesName"
placeholder="请输入仓库名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="是否启用" prop="isEnabled">
<el-select
v-model="queryParams.isEnabled"
placeholder="请选择"
clearable
style="width: 180px"
>
<el-option label="是" value="1" />
<el-option label="否" value="0" />
</el-select>
</el-form-item> -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="loading"
:data="warehousesList"
:max-height="380"
highlight-current-row
@current-change="handleCurrentChange"
@row-dblclick="handleRowDblClick"
style="flex: 1; min-height: 0;"
>
<el-table-column type="index" label="#" width="60" align="center" />
<el-table-column label="仓库编码" prop="warehousesCode" width="150" />
<el-table-column label="仓库名称" prop="warehousesName" min-width="220" show-overflow-tooltip />
<el-table-column label="仓库类型" prop="warehouseType" width="120" align="center">
<template slot-scope="scope">
<span v-if="scope.row.warehouseType === 1">普通仓</span>
<span v-else-if="scope.row.warehouseType === 2">危险品仓</span>
<span v-else-if="scope.row.warehouseType === 3">冷藏仓</span>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="地址" prop="address" min-width="200" show-overflow-tooltip />
<el-table-column label="是否启用" prop="isEnabled" width="110" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.isEnabled === '1' || scope.row.isEnabled === 1 ? 'success' : 'info'" size="mini">
{{ scope.row.isEnabled === '1' || scope.row.isEnabled === 1 ? '是' : '否' }}
</el-tag>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="close">取 消</el-button>
<el-button type="primary" @click="confirmSelection">确 定</el-button>
</div>
</el-dialog>
</template>
<script>
import { listWarehousesForSelector } from "@/api/inventory/warehouses"
export default {
name: "WarehouseSelector",
props: {
value: {
type: Boolean,
default: false
}
},
data() {
return {
warehousesList: [],
loading: false,
total: 0,
currentWarehouse: null,
queryParams: {
pageNum: 1,
pageSize: 10,
warehousesCode: null,
warehousesName: null,
isEnabled: "1"
}
}
},
computed: {
dialogVisible: {
get() {
return this.value
},
set(val) {
this.$emit("input", val)
}
}
},
watch: {
dialogVisible(val) {
if (val) {
this.$nextTick(() => {
this.init()
})
} else {
this.resetState()
}
}
},
methods: {
init() {
if (this.warehousesList.length === 0) {
this.getList()
}
},
resetState() {
this.currentWarehouse = null
},
getList() {
this.loading = true
listWarehousesForSelector(this.queryParams)
.then(res => {
this.warehousesList = res.rows || []
this.total = res.total || 0
})
.finally(() => {
this.loading = false
})
},
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
resetQuery() {
this.queryParams = {
pageNum: 1,
pageSize: 10,
warehousesCode: null,
warehousesName: null,
isEnabled: "1"
}
this.getList()
},
handleCurrentChange(row) {
this.currentWarehouse = row
},
handleRowDblClick(row) {
this.currentWarehouse = row
this.confirmSelection()
},
confirmSelection() {
if (!this.currentWarehouse) {
this.$message.warning("请先选择一个仓库")
return
}
const payload = {
warehousesCode: this.currentWarehouse.warehousesCode,
warehousesName: this.currentWarehouse.warehousesName,
warehouseId: this.currentWarehouse.id
}
this.$emit("selected", payload)
this.dialogVisible = false
},
close() {
this.dialogVisible = false
},
refresh() {
this.getList()
}
}
}
</script>
<style scoped>
.warehouse-selector-dialog /deep/ .el-dialog__body {
padding: 10px 20px 0;
min-height: 500px;
display: flex;
flex-direction: column;
}
.warehouse-selector-body {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
}
.warehouse-selector-form {
margin-bottom: 10px;
}
.title-tip {
font-size: 12px;
color: #999;
margin-left: 8px;
}
</style>
...@@ -23,5 +23,16 @@ ...@@ -23,5 +23,16 @@
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
...@@ -14,11 +14,13 @@ import org.springframework.web.bind.annotation.PathVariable; ...@@ -14,11 +14,13 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.alibaba.excel.EasyExcel;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.inventory.domain.Inventory; import com.ruoyi.inventory.domain.Inventory;
import com.ruoyi.inventory.domain.vo.InventorySummaryVO;
import com.ruoyi.inventory.service.IInventoryService; import com.ruoyi.inventory.service.IInventoryService;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
...@@ -48,6 +50,28 @@ public class InventoryController extends BaseController ...@@ -48,6 +50,28 @@ public class InventoryController extends BaseController
return getDataTable(list); return getDataTable(list);
} }
/** /**
* 查询库存列表(按物料汇总统计)
*/
@PreAuthorize("@ss.hasPermi('inventory:inventory:list')")
@GetMapping("/listCount")
public TableDataInfo listCount(Inventory inventory)
{
startPage();
List<InventorySummaryVO> list = inventoryService.selectInventorySummaryList(inventory);
return getDataTable(list);
}
/**
* 查询库存明细列表(根据物料标识及检索条件)
*/
@PreAuthorize("@ss.hasPermi('inventory:inventory:list')")
@GetMapping("/detailList")
public TableDataInfo detailList(Inventory inventory)
{
List<Inventory> list = inventoryService.selectInventoryDetailList(inventory);
return getDataTable(list);
}
/**
* 查询库存列表 * 查询库存列表
*/ */
@PreAuthorize("@ss.hasPermi('inventory:inventory:list')") @PreAuthorize("@ss.hasPermi('inventory:inventory:list')")
...@@ -70,6 +94,27 @@ public class InventoryController extends BaseController ...@@ -70,6 +94,27 @@ public class InventoryController extends BaseController
ExcelUtil<Inventory> util = new ExcelUtil<Inventory>(Inventory.class); ExcelUtil<Inventory> util = new ExcelUtil<Inventory>(Inventory.class);
util.exportExcel(response, list, "库存数据"); util.exportExcel(response, list, "库存数据");
} }
/**
* 导出库存列表(使用EasyExcel)
*/
@PreAuthorize("@ss.hasPermi('inventory:inventory:export')")
@Log(title = "库存", businessType = BusinessType.EXPORT)
@PostMapping("/exportExcel")
public void exportExcel(HttpServletResponse response, Inventory inventory)
{
try {
List<InventorySummaryVO> list = inventoryService.selectInventorySummaryList(inventory);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = "库存明细数据_" + System.currentTimeMillis() + ".xlsx";
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + java.net.URLEncoder.encode(fileName, "UTF-8"));
EasyExcel.write(response.getOutputStream(), InventorySummaryVO.class)
.sheet("库存明细")
.doWrite(list);
} catch (Exception e) {
e.printStackTrace();
}
}
/** /**
* 获取库存详细信息 * 获取库存详细信息
......
...@@ -38,6 +38,9 @@ public class Inventory extends BaseEntity ...@@ -38,6 +38,9 @@ public class Inventory extends BaseEntity
/** 批次ID 检索条件 */ /** 批次ID 检索条件 */
@Excel(name = "仓库ID ") @Excel(name = "仓库ID ")
private String warehousesId; private String warehousesId;
/** 仓库编码 检索条件 */
private String warehousesCode;
/** 库位ID 检索条件 */ /** 库位ID 检索条件 */
@Excel(name = "库位ID 检索条件") @Excel(name = "库位ID 检索条件")
private String locationId; private String locationId;
...@@ -106,6 +109,9 @@ public class Inventory extends BaseEntity ...@@ -106,6 +109,9 @@ public class Inventory extends BaseEntity
@Excel(name = "排序号") @Excel(name = "排序号")
private String updateUserCode; private String updateUserCode;
/** 预警类型 */
private String alertType;
public String getWarehousesId() { public String getWarehousesId() {
return warehousesId; return warehousesId;
} }
...@@ -324,6 +330,26 @@ public class Inventory extends BaseEntity ...@@ -324,6 +330,26 @@ public class Inventory extends BaseEntity
return updateUserCode; return updateUserCode;
} }
public void setWarehousesCode(String warehousesCode)
{
this.warehousesCode = warehousesCode;
}
public String getWarehousesCode()
{
return warehousesCode;
}
public void setAlertType(String alertType)
{
this.alertType = alertType;
}
public String getAlertType()
{
return alertType;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
......
...@@ -80,4 +80,20 @@ public interface InventoryMapper ...@@ -80,4 +80,20 @@ public interface InventoryMapper
* @version 1.0 * @version 1.0
*/ */
List<StocktakeItems> selectstocktakeItemsList(); List<StocktakeItems> selectstocktakeItemsList();
/**
* 按物料汇总统计库存
*
* @param inventory 库存查询条件
* @return 库存汇总统计集合
*/
public List<com.ruoyi.inventory.domain.vo.InventorySummaryVO> selectInventorySummaryList(Inventory inventory);
/**
* 查询库存明细列表(根据物料标识及检索条件)
*
* @param inventory 库存查询条件
* @return 库存明细集合
*/
public List<Inventory> selectInventoryDetailList(Inventory inventory);
} }
...@@ -90,5 +90,19 @@ public interface IInventoryService ...@@ -90,5 +90,19 @@ public interface IInventoryService
*/ */
public List<StocktakeItems> selectstocktakeItemsList(); public List<StocktakeItems> selectstocktakeItemsList();
/**
* 按物料汇总统计库存
*
* @param inventory 库存查询条件
* @return 库存汇总统计集合
*/
public List<com.ruoyi.inventory.domain.vo.InventorySummaryVO> selectInventorySummaryList(Inventory inventory);
/**
* 查询库存明细列表(根据物料标识及检索条件)
*
* @param inventory 库存查询条件
* @return 库存明细集合
*/
public List<Inventory> selectInventoryDetailList(Inventory inventory);
} }
...@@ -205,4 +205,28 @@ public class InventoryServiceImpl implements IInventoryService ...@@ -205,4 +205,28 @@ public class InventoryServiceImpl implements IInventoryService
public List<StocktakeItems> selectstocktakeItemsList(){ public List<StocktakeItems> selectstocktakeItemsList(){
return inventoryMapper.selectstocktakeItemsList(); return inventoryMapper.selectstocktakeItemsList();
} }
/**
* 按物料汇总统计库存
*
* @param inventory 库存查询条件
* @return 库存汇总统计集合
*/
@Override
public List<com.ruoyi.inventory.domain.vo.InventorySummaryVO> selectInventorySummaryList(Inventory inventory)
{
return inventoryMapper.selectInventorySummaryList(inventory);
}
/**
* 查询库存明细列表(根据物料标识及检索条件)
*
* @param inventory 库存查询条件
* @return 库存明细集合
*/
@Override
public List<Inventory> selectInventoryDetailList(Inventory inventory)
{
return inventoryMapper.selectInventoryDetailList(inventory);
}
} }
...@@ -10,6 +10,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...@@ -10,6 +10,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="orderId" column="order_id" /> <result property="orderId" column="order_id" />
<result property="materialId" column="material_id" /> <result property="materialId" column="material_id" />
<result property="batchId" column="batch_id" /> <result property="batchId" column="batch_id" />
<result property="warehousesCode" column="warehouses_code" />
<result property="locationId" column="location_id" /> <result property="locationId" column="location_id" />
<result property="ownerId" column="owner_id" /> <result property="ownerId" column="owner_id" />
<result property="quantity" column="quantity" /> <result property="quantity" column="quantity" />
...@@ -54,6 +55,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...@@ -54,6 +55,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap> </resultMap>
<resultMap type="com.ruoyi.inventory.domain.vo.InventorySummaryVO" id="InventorySummaryResult">
<result property="materialId" column="material_id" />
<result property="materialName" column="material_name" />
<result property="inventoryTypeName" column="inventory_type_name" />
<result property="warehousesCode" column="warehouses_code" />
<result property="warehouseName" column="warehouse_name" />
<result property="locationId" column="location_id" />
<result property="locationName" column="location_name" />
<result property="ownerId" column="owner_id" />
<result property="ownerName" column="owner_name" />
<result property="totalQuantity" column="total_quantity" />
<result property="totalLockedQuantity" column="total_locked_quantity" />
<result property="totalAvailableQuantity" column="total_available_quantity" />
<result property="totalWeight" column="total_weight" />
<result property="totalVolume" column="total_volume" />
<result property="inventoryStatusName" column="inventory_status_name" />
</resultMap>
<sql id="selectInventoryVo"> <sql id="selectInventoryVo">
select id, inventory_type,warehouses_id, order_id, material_id, batch_id, location_id, owner_id, quantity, locked_quantity, unit_weight, total_weight, total_volume, production_date, expiration_date, inventory_status, last_inbound_time, last_outbound_time, is_used, sort_no, create_time, create_user_code, update_time, update_user_code from inventory select id, inventory_type,warehouses_id, order_id, material_id, batch_id, location_id, owner_id, quantity, locked_quantity, unit_weight, total_weight, total_volume, production_date, expiration_date, inventory_status, last_inbound_time, last_outbound_time, is_used, sort_no, create_time, create_user_code, update_time, update_user_code from inventory
</sql> </sql>
...@@ -85,6 +104,62 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...@@ -85,6 +104,62 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where> </where>
</select> </select>
<!-- 按物料汇总统计库存 -->
<select id="selectInventorySummaryList" parameterType="Inventory" resultMap="InventorySummaryResult">
select
i.material_id,
m.material_name,
case i.inventory_type when 1 then '普通' when 2 then '退库' else '未知' end as inventory_type_name,
i.warehouses_code,
w.warehouses_name as warehouse_name,
i.location_id,
sl.location_name,
i.owner_id,
o.owner_name,
sum(i.quantity) as total_quantity,
sum(i.locked_quantity) as total_locked_quantity,
sum(i.quantity - ifnull(i.locked_quantity, 0)) as total_available_quantity,
sum(ifnull(i.total_weight, 0)) as total_weight,
sum(ifnull(i.total_volume, 0)) as total_volume,
case max(i.inventory_status) when 0 then '已出库' when 1 then '正常' else '未知' end as inventory_status_name
from inventory i
left join materials m on i.material_id = m.material_code
left join warehouses w on i.warehouses_code = w.warehouses_code
left join storage_locations sl on i.location_id = sl.location_code
left join owners o on i.owner_id = o.owner_code
<where>
<if test="inventoryType != null "> and i.inventory_type = #{inventoryType}</if>
<if test="materialId != null and materialId != ''"> and (i.material_id like concat('%', #{materialId}, '%') or m.material_code like concat('%', #{materialId}, '%'))</if>
<if test="batchId != null and batchId != ''"> and i.batch_id = #{batchId}</if>
<if test="warehousesCode != null and warehousesCode != ''"> and i.warehouses_code = #{warehousesCode}</if>
<if test="locationId != null and locationId != ''"> and i.location_id = #{locationId}</if>
<if test="ownerId != null and ownerId != ''"> and i.owner_id = #{ownerId}</if>
<if test="inventoryStatus != null "> and i.inventory_status = #{inventoryStatus}</if>
<if test="isUsed != null "> and i.is_used = #{isUsed}</if>
<!-- 预警类型过滤(需要根据业务逻辑判断,这里暂时不实现) -->
</where>
group by i.material_id, i.warehouses_code, i.location_id, i.owner_id, i.inventory_type, i.inventory_status
order by i.material_id, i.warehouses_code, i.location_id
</select>
<!-- 查询库存明细列表(根据物料标识及检索条件) -->
<select id="selectInventoryDetailList" parameterType="Inventory" resultMap="InventoryResult">
<include refid="selectInventoryVo"/>
<where>
<if test="inventoryType != null "> and inventory_type = #{inventoryType}</if>
<if test="orderId != null and orderId != ''"> and order_id = #{orderId}</if>
<if test="materialId != null and materialId != ''"> and material_id = #{materialId}</if>
<if test="batchId != null and batchId != ''"> and batch_id = #{batchId}</if>
<if test="warehousesCode != null and warehousesCode != ''"> and warehouses_code = #{warehousesCode}</if>
<if test="locationId != null and locationId != ''"> and location_id = #{locationId}</if>
<if test="ownerId != null and ownerId != ''"> and owner_id = #{ownerId}</if>
<if test="inventoryStatus != null "> and inventory_status = #{inventoryStatus}</if>
<if test="isUsed != null "> and is_used = #{isUsed}</if>
<if test="warehousesId != null "> and warehouses_id = #{warehousesId}</if>
</where>
order by material_id, warehouses_code, location_id, create_time desc
</select>
<select id="selectInventory" parameterType="Inventory" resultMap="InventoryResult"> <select id="selectInventory" parameterType="Inventory" resultMap="InventoryResult">
<include refid="selectInventoryVo"/> <include refid="selectInventoryVo"/>
<where> <where>
...@@ -92,6 +167,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...@@ -92,6 +167,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="orderId != null and orderId != ''"> and order_id = #{orderId}</if> <if test="orderId != null and orderId != ''"> and order_id = #{orderId}</if>
<if test="materialId != null and materialId != ''"> and material_id = #{materialId}</if> <if test="materialId != null and materialId != ''"> and material_id = #{materialId}</if>
<if test="batchId != null and batchId != ''"> and batch_id = #{batchId}</if> <if test="batchId != null and batchId != ''"> and batch_id = #{batchId}</if>
<if test="warehousesCode != null and warehousesCode != ''"> and warehouses_code = #{warehousesCode}</if>
<if test="locationId != null and locationId != ''"> and location_id = #{locationId}</if> <if test="locationId != null and locationId != ''"> and location_id = #{locationId}</if>
<if test="ownerId != null and ownerId != ''"> and owner_id = #{ownerId}</if> <if test="ownerId != null and ownerId != ''"> and owner_id = #{ownerId}</if>
<if test="quantity != null "> and quantity = #{quantity}</if> <if test="quantity != null "> and quantity = #{quantity}</if>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论