Compare commits
3 Commits
10a80587f1
...
fd34fe0c72
| Author | SHA1 | Date | |
|---|---|---|---|
| fd34fe0c72 | |||
| 14dc9964d5 | |||
| 33424d0a72 |
@@ -256,6 +256,9 @@ public class RequisitionIssueAppServiceImpl implements IRequisitionIssueAppServi
|
||||
*/
|
||||
@Override
|
||||
public R<?> submitApproval(String busNo) {
|
||||
// 提交审批前校验库存,防止超库存单据进入审批流
|
||||
this.validateRequisitionStockByBusNo(busNo);
|
||||
|
||||
// 单据提交审核
|
||||
boolean result = supplyRequestService.submitApproval(busNo);
|
||||
return result ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null))
|
||||
@@ -419,4 +422,80 @@ public class RequisitionIssueAppServiceImpl implements IRequisitionIssueAppServi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据单据号校验领用数量是否超过源仓库实际库存(提交审批前调用)
|
||||
*
|
||||
* @param busNo 单据号
|
||||
*/
|
||||
private void validateRequisitionStockByBusNo(String busNo) {
|
||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||
// 通过单据详情查询已保存的单据明细
|
||||
R<List<IssueDetailDto>> detailResult = this.getDetail(busNo);
|
||||
if (detailResult.getCode() != 200 || detailResult.getData() == null) {
|
||||
return;
|
||||
}
|
||||
List<IssueDetailDto> detailList = detailResult.getData();
|
||||
for (IssueDetailDto detail : detailList) {
|
||||
Long itemId = detail.getItemId();
|
||||
String lotNumber = detail.getLotNumber();
|
||||
Long sourceLocationId = detail.getSourceLocationId();
|
||||
BigDecimal reqQuantity = detail.getItemQuantity();
|
||||
String itemTable = CommonConstants.TableName.MED_MEDICATION_DEFINITION;
|
||||
// 根据药品类型判断表名
|
||||
if (ItemType.DEVICE.getValue().equals(detail.getItemType())) {
|
||||
itemTable = CommonConstants.TableName.ADM_DEVICE_DEFINITION;
|
||||
}
|
||||
|
||||
// 查询定义信息(拆零比、单位)
|
||||
BigDecimal partPercent = BigDecimal.ONE;
|
||||
String unitCode = detail.getUnitCode();
|
||||
String minUnitCode = detail.getMinUnitCode();
|
||||
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(itemTable)) {
|
||||
MedicationDefinition medDef = medicationDefinitionService.getById(itemId);
|
||||
if (medDef != null) {
|
||||
unitCode = medDef.getUnitCode();
|
||||
minUnitCode = medDef.getMinUnitCode();
|
||||
if (medDef.getPartPercent() != null) {
|
||||
partPercent = medDef.getPartPercent();
|
||||
}
|
||||
}
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(itemTable)) {
|
||||
DeviceDefinition devDef = deviceDefinitionService.getById(itemId);
|
||||
if (devDef != null) {
|
||||
unitCode = devDef.getUnitCode();
|
||||
minUnitCode = devDef.getMinUnitCode();
|
||||
if (devDef.getPartPercent() != null) {
|
||||
partPercent = devDef.getPartPercent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 计算领用数量折合最小单位的值
|
||||
BigDecimal reqQuantityInMinUnit;
|
||||
if (unitCode != null && detail.getUnitCode().equals(unitCode)) {
|
||||
reqQuantityInMinUnit = reqQuantity.multiply(partPercent);
|
||||
} else {
|
||||
reqQuantityInMinUnit = reqQuantity;
|
||||
}
|
||||
|
||||
// 查询源仓库实际库存
|
||||
List<InventoryItem> inventoryItemList = inventoryItemService.selectInventoryByItemId(
|
||||
itemId, lotNumber, sourceLocationId, tenantId);
|
||||
|
||||
// 累加总库存
|
||||
BigDecimal totalStock = BigDecimal.ZERO;
|
||||
for (InventoryItem inventoryItem : inventoryItemList) {
|
||||
if (inventoryItem.getLocationId().equals(sourceLocationId)) {
|
||||
totalStock = totalStock.add(inventoryItem.getQuantity());
|
||||
}
|
||||
}
|
||||
|
||||
// 比较领用数量与库存
|
||||
if (reqQuantityInMinUnit.compareTo(totalStock) > 0) {
|
||||
throw new ServiceException("提交失败,单据中存在领用数量超过库存的明细,请核对后重新保存");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -501,8 +501,8 @@ const submit = () => {
|
||||
if (res.code === 200) {
|
||||
ElMessage.success(res.msg || (props.isEditMode ? '修改成功' : '保存成功'));
|
||||
applicationList.value = [];
|
||||
resetForm();
|
||||
emits('submitOk');
|
||||
resetForm();
|
||||
} else {
|
||||
ElMessage.error(res.msg || '保存失败');
|
||||
}
|
||||
|
||||
@@ -982,6 +982,16 @@ function handleSubmitApproval() {
|
||||
} else if (!form.purchaseinventoryList[length - 1].isSave) {
|
||||
proxy.$modal.msgWarning('第' + length + '行单据未保存,请先保存');
|
||||
} else {
|
||||
// 提交审批前逐行校验库存,防止超库存单据进入审批
|
||||
for (let i = 0; i < form.purchaseinventoryList.length; i++) {
|
||||
const line = form.purchaseinventoryList[i];
|
||||
if (!line) continue;
|
||||
const err = validateRequisitionQtyVsStock(line, i + 1);
|
||||
if (err) {
|
||||
proxy.$modal.msgWarning(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
submitApproval(receiptHeaderForm.busNo).then((response) => {
|
||||
if (response.code == 200) {
|
||||
proxy.$modal.msgSuccess('提交审批成功');
|
||||
|
||||
@@ -781,7 +781,7 @@
|
||||
</el-table>
|
||||
|
||||
<!-- 底部分页区 -->
|
||||
<div class="pagination-container apply-pagination" style="margin-top: 10px; padding-bottom: 20px">
|
||||
<div class="pagination-container apply-pagination">
|
||||
<pagination
|
||||
v-show="applyTotal > 0"
|
||||
:total="applyTotal"
|
||||
@@ -792,12 +792,9 @@
|
||||
@pagination="getSurgicalScheduleList"
|
||||
/>
|
||||
</div>
|
||||
<!-- 分页与底部操作区之间的间隔 -->
|
||||
<div style="height: 48px"></div>
|
||||
|
||||
<!-- 底部操作区 -->
|
||||
<template #footer>
|
||||
<div class="dialog-footer" style="margin-top: 24px; padding-top: 12px; border-top: 1px solid #ebeef5">
|
||||
<div class="dialog-footer" style="padding-top: 12px; border-top: 1px solid #ebeef5">
|
||||
<el-button @click="cancelApplyDialog">取消</el-button>
|
||||
<el-button type="primary" @click="confirmApply">确认</el-button>
|
||||
</div>
|
||||
@@ -2408,15 +2405,14 @@ function getRowClassName({ row, rowIndex }) {
|
||||
|
||||
/* 手术申请查询弹窗 — 分页与footer间距 */
|
||||
.surgery-apply-dialog :deep(.el-dialog__body) {
|
||||
padding-bottom: 32px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
.surgery-apply-dialog :deep(.el-dialog__footer) {
|
||||
padding-top: 0;
|
||||
padding-top: 8px;
|
||||
}
|
||||
.surgery-apply-dialog :deep(.apply-pagination) {
|
||||
padding-bottom: 24px;
|
||||
margin-bottom: 16px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
.surgery-apply-dialog :deep(.apply-pagination .el-pagination) {
|
||||
margin-right: 80px;
|
||||
@@ -2436,17 +2432,16 @@ function getRowClassName({ row, rowIndex }) {
|
||||
<style>
|
||||
/* 手术申请查询弹窗 — 非 scoped 确保穿透 teleport */
|
||||
.surgery-apply-dialog .apply-pagination {
|
||||
padding-bottom: 24px !important;
|
||||
margin-bottom: 16px !important;
|
||||
border-bottom: 1px solid #ebeef5 !important;
|
||||
padding-top: 12px !important;
|
||||
padding-bottom: 16px !important;
|
||||
}
|
||||
.surgery-apply-dialog .apply-pagination .el-pagination {
|
||||
margin-right: 80px !important;
|
||||
}
|
||||
.surgery-apply-dialog .el-dialog__body {
|
||||
padding-bottom: 32px !important;
|
||||
padding-bottom: 16px !important;
|
||||
}
|
||||
.surgery-apply-dialog .el-dialog__footer {
|
||||
padding-top: 0 !important;
|
||||
padding-top: 8px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user