feat(sip): 新增库存出库价同步及应付单生成功能

- 新增 InventoryInfo.listByDeliveryId 方法以支持按出库单查询库存信息
- 在 InventoryDeliveryServiceImpl 中实现保存出库信息时同步更新出库价
- 实现出库时自动生成应付单逻辑,包括税率配置读取与金额计算
- 增加 selectOutPriceByCode 查询用于获取项目产品的价格信息
- 扩展 VendorInfo 支持付款类型枚举,区分入库付款与出库付款
- 修改 OmsPayableBill 实体类,增加项目编码、名称等字段并优化结构
- 优化应付单 Controller 接口,支持更灵活的查询条件
- 重构应付单 Mapper XML 文件,增强关联查询与筛选功能
- 在应付单 Service 层新增事务控制与默认付款计划创建逻辑
- 移除前端精确货币舍入工具函数,改用 decimal.js 进行高精度运算
- 注册全局计算工具至 Vue 实例,替换原有金额计算方式提升准确性
dev_1.0.0
chenhao 2025-12-04 10:53:27 +08:00
parent fb00d486e0
commit 1a4f64865a
25 changed files with 312 additions and 95 deletions

View File

@ -48,7 +48,8 @@
"vue-cropper": "0.5.5",
"vue-router": "3.4.9",
"vuedraggable": "2.24.3",
"vuex": "3.6.0"
"vuex": "3.6.0",
"decimal.js": "10.4.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "4.4.6",

View File

@ -4,7 +4,9 @@ import Cookies from 'js-cookie'
import Element from 'element-ui'
import './assets/styles/element-variables.scss'
import * as Calc from '@/utils/calc'
Vue.prototype.$calc = Calc // 全局挂载
import '@/assets/styles/index.scss' // global css
import '@/assets/styles/ruoyi.scss' // ruoyi css
import App from './App'

View File

@ -0,0 +1,38 @@
import Decimal from 'decimal.js'
// 默认保留小数位(你可根据业务修改,比如金额一般 2 位)
const DEFAULT_DP = 2
// 内部方法:统一转换 Decimal避免 null/undefined 报错
function D(n) {
return new Decimal(n || 0)
}
/**
* 保留小数位 & 四舍五入
* @param value 数值
* @param dp 保留位数默认 DEFAULT_DP
*/
export function toFixed(value, dp = DEFAULT_DP) {
return D(value).toDecimalPlaces(dp).toNumber()
}
// 加法
export function add(a, b, dp = DEFAULT_DP) {
return D(a).plus(b).toDecimalPlaces(dp).toNumber()
}
// 减法
export function sub(a, b, dp = DEFAULT_DP) {
return D(a).minus(b).toDecimalPlaces(dp).toNumber()
}
// 乘法
export function mul(a, b, dp = DEFAULT_DP) {
return D(a).times(b).toDecimalPlaces(dp).toNumber()
}
// 除法
export function div(a, b, dp = DEFAULT_DP) {
return D(a).div(b || 1).toDecimalPlaces(dp).toNumber()
}

View File

@ -226,9 +226,3 @@ export function getNormalPath(p) {
export function blobValidate(data) {
return data.type !== 'application/json'
}
export function preciseCurrencyRound(amount,decimalPlace) {
if (decimalPlace){
return Number(Math.round(amount + `e${decimalPlace}`) + `e-${decimalPlace}`);
}
return Number(Math.round(amount + 'e2') + 'e-2');
}

View File

@ -206,7 +206,6 @@
</template>
<script>
import {preciseCurrencyRound} from "@/utils/ruoyi";
export default {
name: "ConfigInfo",
@ -302,8 +301,9 @@ export default {
if (discount === 1) {
return product.allPrice;
}
const roundedDiscountedUnitPrice = preciseCurrencyRound( product.price * discount);
return roundedDiscountedUnitPrice * product.quantity;
const roundedDiscountedUnitPrice = this.$calc.mul( product.price,discount);
return this.$calc.mul(roundedDiscountedUnitPrice , product.quantity);
},
calculateTotal(productList, discount) {
if (!productList) return 0;

View File

@ -254,7 +254,7 @@
<script>
import SelectProduct from '@/views/system/product/selectProduct.vue';
import {preciseCurrencyRound} from "@/utils/ruoyi";
export default {
name: 'ProductConfig',
@ -322,8 +322,8 @@ export default {
quantity: item.quantity || 0,
taxRate: item.taxRate || 13,
cataloguePriceFormat: this.formatAmount(item.cataloguePrice),
guidanceDiscountFormat: item.guidanceDiscount ? preciseCurrencyRound(item.guidanceDiscount * 100, 2) : '',
discountFormat: item.discount ? preciseCurrencyRound(item.discount * 100, 2) : '',
guidanceDiscountFormat: item.guidanceDiscount ? this.$calc.mul(item.guidanceDiscount, 100) : '',
discountFormat: item.discount ? this.$calc.mul(item.discount, 100) : '',
priceFormat: this.formatAmount(item.price),
allPriceFormat: this.formatAmount(item.allPrice),
catalogueAllPriceFormat: this.formatAmount(item.catalogueAllPrice)
@ -413,9 +413,9 @@ export default {
row.cataloguePrice = product.cataloguePrice;
row.cataloguePriceFormat = this.formatAmount(product.cataloguePrice);
row.guidanceDiscount = product.guidanceDiscount;
row.guidanceDiscountFormat = product.guidanceDiscount ? preciseCurrencyRound(product.guidanceDiscount * 100, 2) : '';
row.guidanceDiscountFormat = product.guidanceDiscount ? this.$calc.mul(product.guidanceDiscount, 100) : '';
row.discount = product.guidanceDiscount || 0;
row.discountFormat = product.guidanceDiscount ? preciseCurrencyRound(product.guidanceDiscount * 100, 2) : '';
row.discountFormat = product.guidanceDiscount ? this.$calc.mul(product.guidanceDiscount, 100) : '';
this.calculateRow(row);
this.emitChange();
@ -439,14 +439,13 @@ export default {
if (isNaN(price)) {
price = 0;
}
row.price = preciseCurrencyRound(price, 2);
row.price = this.$calc.toFixed(price);
row.priceFormat = this.formatAmount(row.price);
// 0
if (row.cataloguePrice && row.cataloguePrice > 0) {
const discount = row.price / row.cataloguePrice;
row.discount = preciseCurrencyRound(discount, 4); // 4
row.discountFormat = preciseCurrencyRound(discount * 100, 2); // 2
row.discount = this.$calc.div(row.price,row.cataloguePrice,4) // 4
row.discountFormat = this.$calc.mul(row.discount ,100, 2); // 2
} else {
// 00
row.discount = 0;
@ -454,9 +453,9 @@ export default {
}
//
row.allPrice = preciseCurrencyRound(row.price * row.quantity, 2);
row.allPrice = this.$calc.mul(row.price , row.quantity, 2);
row.allPriceFormat = this.formatAmount(row.allPrice);
row.catalogueAllPrice = preciseCurrencyRound(row.cataloguePrice * row.quantity, 2);
row.catalogueAllPrice = this.$calc.mul(row.cataloguePrice ,row.quantity, 2);
row.catalogueAllPriceFormat = this.formatAmount(row.catalogueAllPrice);
this.emitChange();
@ -466,17 +465,17 @@ export default {
return;
}
// = *
const discount = row.discountFormat ? row.discountFormat / 100 : 0;
row.discount = preciseCurrencyRound(discount, 4);
row.price =preciseCurrencyRound(row.cataloguePrice * discount, 2);
const discount = row.discountFormat ? this.$calc.div(row.discountFormat , 100,4) : 0;
row.discount = discount;
row.price =this.$calc.mul(row.cataloguePrice , discount, 2);
row.priceFormat = this.formatAmount(row.price);
// = *
row.allPrice = preciseCurrencyRound(row.price * row.quantity, 2);
row.allPrice = this.$calc.mul(row.price , row.quantity, 2);
row.allPriceFormat = this.formatAmount(row.allPrice);
// = *
row.catalogueAllPrice = preciseCurrencyRound(row.cataloguePrice * row.quantity, 2);
row.catalogueAllPrice = this.$calc.mul(row.cataloguePrice , row.quantity, 2);
row.catalogueAllPriceFormat = this.formatAmount(row.catalogueAllPrice);
this.emitChange();
@ -535,7 +534,7 @@ export default {
if (isNaN(cataloguePrice)) {
cataloguePrice = 0;
}
row.cataloguePrice = preciseCurrencyRound(cataloguePrice, 2);
row.cataloguePrice = this.$calc.toFixed(cataloguePrice, 2);
row.cataloguePriceFormat = this.formatAmount(row.cataloguePrice);
// Recalculate based on new catalogue price

View File

@ -188,7 +188,7 @@ import { listAllVendor } from "@/api/base/vendor";
import SelectUser from "@/views/system/user/selectUser";
import SelectProduct from "@/views/system/product/selectProduct";
import { getDicts } from "@/api/system/dict/data";
import {preciseCurrencyRound} from "@/utils/ruoyi";
export default {
name: "PurchaseOrderDetail",
@ -271,7 +271,7 @@ export default {
computed: {
totalAmountWithTax() {
const total = this.form.omsPurchaseOrderItemList?.reduce((acc, cur) => acc + (cur.amountTotal || 0), 0);
this.form.totalAmount=preciseCurrencyRound(total) || 0;
this.form.totalAmount=this.$calc.toFixed(total) || 0;
return this.form.totalAmount;
},
totalAmountWithoutTax() {
@ -280,10 +280,10 @@ export default {
const taxRate = cur.taxRate || 0;
return acc + (amount / (1 + taxRate));
}, 0);
return (preciseCurrencyRound(total)) || 0;
return (this.$calc.toFixed(total)) || 0;
},
totalTaxAmount() {
return (preciseCurrencyRound((this.totalAmountWithTax - this.totalAmountWithoutTax )) ) || 0;
return this.$calc.sub(this.totalAmountWithTax , this.totalAmountWithoutTax ) || 0;
}
},
watch: {
@ -392,8 +392,8 @@ export default {
/** 计算含税小计 */
calculateRowTotal(row) {
if (row.quantity != null && row.price != null) {
row.amountTotal = preciseCurrencyRound(row.quantity * row.price);
row.taxTotal = row.amountTotal - preciseCurrencyRound(row.amountTotal / (1 + row.taxRate));
row.amountTotal = this.$calc.mul(row.quantity , row.price);
row.taxTotal = row.amountTotal - this.$calc.div(row.amountTotal , (1 + row.taxRate));
} else {
row.amountTotal = 0;
row.taxTotal = 0;

View File

@ -226,7 +226,7 @@
import {getPurchaseorder, getPurchaseOrderHistory} from "@/api/sip/purchaseorder";
import {listAllVendor} from "@/api/base/vendor";
import {getDicts} from "@/api/system/dict/data";
import {preciseCurrencyRound} from "@/utils/ruoyi";
export default {
@ -277,7 +277,7 @@ export default {
computed: {
totalAmountWithTax() {
const total = this.form.omsPurchaseOrderItemList?.reduce((acc, cur) => acc + (cur.amountTotal || 0), 0);
return preciseCurrencyRound(total) || 0;
return this.$calc.toFixed(total) || 0;
},
totalAmountWithoutTax() {
const total = this.form.omsPurchaseOrderItemList?.reduce((acc, cur) => {
@ -285,10 +285,10 @@ export default {
const taxRate = cur.taxRate || 0;
return acc + (amount / (1 + taxRate));
}, 0);
return (preciseCurrencyRound(total)) || 0;
return (this.$calc.toFixed(total)) || 0;
},
totalTaxAmount() {
return (preciseCurrencyRound((this.totalAmountWithTax - this.totalAmountWithoutTax))) || 0;
return (this.$calc.sub(this.totalAmountWithTax , this.totalAmountWithoutTax)) || 0;
}
},
watch: {

View File

@ -1,15 +1,13 @@
package com.ruoyi.sip.controller;
import java.util.List;
import com.ruoyi.sip.domain.OmsPaymentBill;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.sip.domain.OmsPayableBill;
@ -18,6 +16,10 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.sip.service.IOmsPaymentBillService;
import com.ruoyi.sip.service.IOmsInvoiceReceiptBillService;
import com.ruoyi.sip.domain.OmsInvoiceReceiptBill;
import org.springframework.ui.ModelMap;
/**
* Controller
@ -34,6 +36,12 @@ public class OmsPayableBillController extends BaseController
@Autowired
private IOmsPayableBillService omsPayableBillService;
@Autowired
private IOmsPaymentBillService omsPaymentBillService;
@Autowired
private IOmsInvoiceReceiptBillService omsInvoiceReceiptBillService;
@RequiresPermissions("finance:payable:view")
@GetMapping()
public String payable()
@ -47,7 +55,7 @@ public class OmsPayableBillController extends BaseController
@RequiresPermissions("finance:payable:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(OmsPayableBill omsPayableBill)
public TableDataInfo list(@RequestBody OmsPayableBill omsPayableBill)
{
startPage();
List<OmsPayableBill> list = omsPayableBillService.selectOmsPayableBillList(omsPayableBill);

View File

@ -16,7 +16,6 @@ import com.ruoyi.common.core.domain.BaseEntity;
* @date 2025-10-22
*/
@Data
@Builder
public class OmsPayableBill extends BaseEntity
{
private static final long serialVersionUID = 1L;
@ -27,6 +26,9 @@ public class OmsPayableBill extends BaseEntity
/** 应付单编号 */
@Excel(name = "应付单编号")
private String payableBillCode;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Excel(name = "生成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 预计付款时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@ -36,7 +38,12 @@ public class OmsPayableBill extends BaseEntity
/** 制造商编码 */
@Excel(name = "制造商编码")
private String vendorCode;
@Excel(name = "制造商名称")
private String vendorName;
@Excel(name = "项目编号")
private String projectCode;
@Excel(name = "项目名称")
private String projectName;
/** 合同编号 */
@Excel(name = "合同编号")
private String orderCode;
@ -48,6 +55,8 @@ public class OmsPayableBill extends BaseEntity
/** 产品类型 */
@Excel(name = "产品类型")
private String productType;
/** 产品编码 */
private String productCode;
/** 含税总价 */
@Excel(name = "含税总价")
@ -61,15 +70,12 @@ public class OmsPayableBill extends BaseEntity
@Excel(name = "税额")
private BigDecimal taxAmount;
/** 关联的付款单ID */
@Excel(name = "关联的付款单ID")
private Long paymentBillId;
/** 关联的收票单ID */
@Excel(name = "关联的收票单ID")
private Long invoiceReceiptBillId;
/** 删除标志0代表存在 2代表删除 */
private String delFlag;
private Date createTimeStart;
private Date createTimeEnd;
}

View File

@ -122,4 +122,18 @@ public class VendorInfo extends BaseEntity
}
}
@Getter
public enum PayTypeEnum {
INNER_PAY("0", "入库付款"),
OUTER_PAY("1", "出库付款"),
;
private final String desc;
private final String code;
PayTypeEnum(String code, String desc) {
this.desc = desc;
this.code = code;
}
}
}

View File

@ -76,4 +76,5 @@ public interface InventoryInfoMapper
List<InventoryInfo> listByProductSnList(List<String> productSnList);
List<InventoryInfo> listByDeliveryId(Long id);
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.sip.mapper;
import java.math.BigDecimal;
import java.util.List;
import com.ruoyi.sip.domain.InventoryOuter;
import com.ruoyi.sip.domain.VendorInfo;
@ -66,4 +67,6 @@ public interface InventoryOuterMapper
int countByOrderCode(String orderCode);
String selectVendorById(Long id);
BigDecimal selectOutPriceByCode(String outerCode);
}

View File

@ -60,4 +60,6 @@ public interface VendorInfoMapper
* @return
*/
public int deleteVendorInfoByVendorIds(String[] vendorIds);
VendorInfo selectVendorInfoByVendorCode(String vendorCode);
}

View File

@ -85,4 +85,6 @@ public interface IInventoryInfoService
void deleteInventoryInfoByInnerIds(String[] idArray);
void recallByOrderCode(List<String> orderCode);
List<InventoryInfo> listByDeliveryId(Long id);
}

View File

@ -20,6 +20,7 @@ public interface IVendorInfoService
* @return
*/
public VendorInfo selectVendorInfoByVendorId(Long vendorId);
public VendorInfo selectVendorInfoByVendorCode(String vendorCode);
/**
*

View File

@ -1,5 +1,7 @@
package com.ruoyi.sip.service.impl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
@ -17,6 +19,7 @@ import com.ruoyi.sip.mapper.InventoryOuterMapper;
import com.ruoyi.sip.service.*;
import com.ruoyi.sip.vo.DeliveryInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.ruoyi.sip.mapper.InventoryDeliveryMapper;
@ -59,6 +62,8 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
@Autowired
private IOmsPayableBillService payableBillService;
@Value("${oms.inventory.innerTax:1.13}")
private String defaultTax;
/**
*
*
@ -104,6 +109,9 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
if (CollUtil.isEmpty(productSnList) && CollUtil.isEmpty(productSnDataList)) {
throw new ServiceException("发货清单为空,保存失败");
}
//修改数据的时候同步修改出库价
BigDecimal bigDecimal = inventoryOuterMapper.selectOutPriceByCode(inventoryDelivery.getOuterCode());
List<OmsInventoryDeliveryDetail> detailList=new ArrayList<>();
if (CollUtil.isEmpty(productSnDataList)) {
List<InventoryInfo> inventoryInfoList = productSnList.stream().map(item -> {
@ -113,6 +121,7 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
info.setInventoryStatus(InventoryInfo.InventoryStatusEnum.OUTER.getCode());
info.setUpdateBy(currentUserId);
info.setUpdateTime(nowDate);
info.setOuterPrice(bigDecimal);
OmsInventoryDeliveryDetail detail = new OmsInventoryDeliveryDetail();
detail.setProductSn(item);
detailList.add(detail);
@ -126,6 +135,7 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
inventoryInfo.setOuterCode(inventoryDelivery.getOuterCode());
inventoryInfo.setUpdateBy(currentUserId);
inventoryInfo.setUpdateTime(nowDate);
inventoryInfo.setOuterPrice(bigDecimal);
OmsInventoryDeliveryDetail detail = new OmsInventoryDeliveryDetail();
detail.setProductSn(inventoryInfo.getProductSn());
detailList.add(detail);
@ -220,6 +230,44 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
productInfoService.updateCumulativeCount(outerSum, inventoryDelivery.getProductCode());
List<ProductInfo> productInfos = productInfoService.selectProductInfoByCodeList(Collections.singletonList(inventoryOuter.getProductCode()));
if (CollUtil.isEmpty(productInfos)) {
throw new ServiceException("未找到对应产品");
}
ProductInfo productInfo = productInfos.get(0);
//生成应付单 取入库价
VendorInfo vendorInfo = vendorInfoService.selectVendorInfoByVendorCode(productInfo.getVendorCode());
if (vendorInfo != null && VendorInfo.PayTypeEnum.OUTER_PAY.getCode().equals(vendorInfo.getPayType())) {
List<InventoryInfo> inventoryInfos = inventoryInfoService.listByDeliveryId(inventoryDelivery.getId());
//生成过应付单的不用再次生成
inventoryInfos = inventoryInfos.stream().filter(item -> StringUtils.isEmpty(item.getPayableBillCode())).collect(Collectors.toList());
if (CollUtil.isEmpty(inventoryInfos)) {
return;
}
OmsPayableBill payableBill = new OmsPayableBill();
payableBill.setProductCode(inventoryOuter.getProductCode());
payableBill.setEstimatedPaymentTime(DateUtils.addDays(DateUtils.getNowDate(), vendorInfo.getPayConfigDay()));
payableBill.setProductType(productInfo.getType());
payableBill.setVendorCode(productInfo.getVendorCode());
payableBill.setInventoryCode(inventoryDelivery.getOuterCode());
BigDecimal allPrice = inventoryInfos.stream().map(InventoryInfo::getInnerPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
payableBill.setTotalPriceWithTax(allPrice);
payableBill.setTotalPriceWithoutTax(allPrice.divide(new BigDecimal(defaultTax), 2, RoundingMode.HALF_UP));
payableBill.setTaxAmount(allPrice.subtract(payableBill.getTotalPriceWithoutTax()));
payableBill.setProjectCode(inventoryDelivery.getProjectCode());
payableBill.setOrderCode(inventoryDelivery.getOrderCode());
payableBillService.insertOmsPayableBill(payableBill);
List<InventoryInfo> saveList = inventoryInfos.stream().map(item -> {
InventoryInfo inventoryInfo = new InventoryInfo();
inventoryInfo.setProductSn(item.getProductSn());
inventoryInfo.setPayableBillCode(payableBill.getPayableBillCode());
return inventoryInfo;
}).collect(Collectors.toList());
inventoryInfoService.saveBatch(saveList);
}
}
@Override

View File

@ -207,5 +207,10 @@ public class InventoryInfoServiceImpl implements IInventoryInfoService {
inventoryInfoMapper.recallByOrderCode(orderCode);
}
@Override
public List<InventoryInfo> listByDeliveryId(Long id) {
return inventoryInfoMapper.listByDeliveryId(id);
}
}

View File

@ -15,6 +15,7 @@ import com.ruoyi.sip.domain.*;
import com.ruoyi.sip.dto.inventory.InventoryInfoExcelDto;
import com.ruoyi.sip.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.sip.mapper.OmsInventoryInnerMapper;
import com.ruoyi.common.core.text.Convert;
@ -49,6 +50,8 @@ public class OmsInventoryInnerServiceImpl implements IOmsInventoryInnerService {
private IOmsPurchaseOrderService purchaseOrderService;
@Autowired
private IOmsPayableBillService payableBillService;
@Value("${oms.inventory.innerTax:1.13}")
private String defaultTax;
/**
*
*
@ -138,24 +141,25 @@ public class OmsInventoryInnerServiceImpl implements IOmsInventoryInnerService {
}
omsInventoryInner.setWarehouseId(warehouseIdList.get(0));
//修改对应的采购订单
purchaseOrderService.innerWarehouse(omsInventoryInner.getItemId(),omsInventoryInner.getQuantity());
//todo 判断制造商是否需要生成应付单
// BigDecimal totalPriceWithTax = inventoryInfoList.stream().map(InventoryInfo::getInnerPrice).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
// //生成应付单
// BigDecimal taxAmount = totalPriceWithTax.multiply(new BigDecimal("0.13")).setScale(2, RoundingMode.HALF_UP);
// OmsPayableBill payableBill = OmsPayableBill.builder()
// .inventoryCode(omsInventoryInner.getInnerCode())
// .vendorCode(omsInventoryInner.getVendorCode())
// .productType(productInfos.get(0).getType())
// .estimatedPaymentTime(DateUtils.addDays(DateUtils.getNowDate(),30))
// .totalPriceWithTax(totalPriceWithTax)
// .taxAmount(taxAmount)
// .totalPriceWithoutTax(totalPriceWithTax.subtract(taxAmount))
// .build();
// payableBillService.insertOmsPayableBill(payableBill);
OmsPayableBill payableBill = new OmsPayableBill();
VendorInfo vendorInfo = vendorInfoService.selectVendorInfoByVendorCode(vendorCode);
if (vendorInfo != null && VendorInfo.PayTypeEnum.INNER_PAY.getCode().equals(vendorInfo.getPayType())) {
BigDecimal reduce = inventoryInfoList.stream().map(InventoryInfo::getInnerPrice).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
//服务金额为单价* 数量 没有具体的详情
BigDecimal totalPriceWithTax =Arrays.asList("11","22").contains(omsInventoryInner.getProductCode())?
reduce.multiply(new BigDecimal(omsInventoryInner.getQuantity())).setScale(2, RoundingMode.HALF_UP)
: reduce;
//生成应付单
payableBill.setInventoryCode(omsInventoryInner.getInnerCode());
payableBill.setVendorCode(omsInventoryInner.getVendorCode());
payableBill.setProductType(productInfos.get(0).getType());
payableBill.setProjectCode(omsInventoryInner.getProductCode());
payableBill.setEstimatedPaymentTime(DateUtils.addDays(DateUtils.getNowDate(), vendorInfo.getPayConfigDay()));
payableBill.setTotalPriceWithTax(totalPriceWithTax);
payableBill.setTotalPriceWithoutTax(totalPriceWithTax.divide(new BigDecimal(defaultTax), 2, RoundingMode.HALF_UP));
payableBill.setTaxAmount(totalPriceWithTax.subtract(payableBill.getTotalPriceWithoutTax()));
payableBillService.insertOmsPayableBill(payableBill);
}
inventoryInfoList.forEach(item->{
item.setInnerCode(omsInventoryInner.getInnerCode());
item.setCreateBy(currentUserId);

View File

@ -6,14 +6,17 @@ import java.util.List;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.sip.mapper.OmsPayableBillMapper;
import com.ruoyi.sip.domain.OmsPayableBill;
import com.ruoyi.sip.mapper.OmsPayableBillMapper;
import com.ruoyi.sip.service.IOmsPayableBillService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.beans.factory.annotation.Autowired;
import com.ruoyi.sip.oms.domain.OmsPayablePaymentPlan;
import com.ruoyi.sip.oms.mapper.OmsPayablePaymentPlanMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* Service
@ -26,6 +29,9 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService {
@Autowired
private OmsPayableBillMapper omsPayableBillMapper;
@Autowired
private OmsPayablePaymentPlanMapper omsPayablePaymentPlanMapper;
/**
*
*
@ -55,12 +61,26 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService {
* @return
*/
@Override
@Transactional
public int insertOmsPayableBill(OmsPayableBill omsPayableBill) {
//生成采购应付单编号
omsPayableBill.setPayableBillCode(generatePayableBillCode());
omsPayableBill.setCreateTime(DateUtils.getNowDate());
omsPayableBill.setCreateBy(ShiroUtils.getUserId().toString());
return omsPayableBillMapper.insertOmsPayableBill(omsPayableBill);
int rows = omsPayableBillMapper.insertOmsPayableBill(omsPayableBill);
// 创建默认付款计划
if (rows > 0) {
OmsPayablePaymentPlan defaultPlan = new OmsPayablePaymentPlan();
defaultPlan.setPayableBillId(omsPayableBill.getId());
defaultPlan.setPlanPaymentDate(omsPayableBill.getEstimatedPaymentTime());
defaultPlan.setPlanAmount(omsPayableBill.getTotalPriceWithTax());
defaultPlan.setPlanRate(new java.math.BigDecimal(100));
defaultPlan.setRemark("默认付款计划");
defaultPlan.setCreateBy(ShiroUtils.getLoginName());
omsPayablePaymentPlanMapper.batchOmsPayablePaymentPlan(java.util.Collections.singletonList(defaultPlan));
}
return rows;
}
/**
@ -99,6 +119,10 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService {
*/
@Override
public int deleteOmsPayableBillByIds(String ids) {
// Also delete payment plans
for (String id : Convert.toStrArray(ids)) {
omsPayablePaymentPlanMapper.deleteOmsPayablePaymentPlanByPayableBillId(Long.valueOf(id));
}
return omsPayableBillMapper.deleteOmsPayableBillByIds(Convert.toStrArray(ids));
}
@ -109,7 +133,9 @@ public class OmsPayableBillServiceImpl implements IOmsPayableBillService {
* @return
*/
@Override
@Transactional
public int deleteOmsPayableBillById(Long id) {
omsPayablePaymentPlanMapper.deleteOmsPayablePaymentPlanByPayableBillId(id);
return omsPayableBillMapper.deleteOmsPayableBillById(id);
}
}

View File

@ -48,6 +48,11 @@ public class VendorInfoServiceImpl implements IVendorInfoService {
return vendorInfoMapper.selectVendorInfoByVendorId(vendorId);
}
@Override
public VendorInfo selectVendorInfoByVendorCode(String vendorCode) {
return vendorInfoMapper.selectVendorInfoByVendorCode(vendorCode);
}
/**
*
*

View File

@ -15,8 +15,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="totalPriceWithTax" column="total_price_with_tax" />
<result property="totalPriceWithoutTax" column="total_price_without_tax" />
<result property="taxAmount" column="tax_amount" />
<result property="paymentBillId" column="payment_bill_id" />
<result property="invoiceReceiptBillId" column="invoice_receipt_bill_id" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
@ -26,23 +24,65 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectOmsPayableBillVo">
select id, payable_bill_code, estimated_payment_time, vendor_code, order_code, inventory_code, product_type, total_price_with_tax, total_price_without_tax, tax_amount, payment_bill_id, invoice_receipt_bill_id, create_by, create_time, update_by, update_time, remark, del_flag from oms_payable_bill
select id, payable_bill_code, estimated_payment_time, vendor_code, order_code, inventory_code, product_type, total_price_with_tax, total_price_without_tax, tax_amount, create_by, create_time, update_by, update_time, remark, del_flag from oms_payable_bill
</sql>
<sql id="selectOmsPayableBillRelationVo">
SELECT
t1.id,
t1.payable_bill_code,
t1.estimated_payment_time,
t1.vendor_code,
t1.order_code,
t1.inventory_code,
t1.product_type,
t1.total_price_with_tax,
t1.total_price_without_tax,
t1.tax_amount,
t1.create_by,
t1.create_time,
t1.update_by,
t1.update_time,
t1.remark,
t1.del_flag ,
t3.project_code,
t3.project_name,
t4.vendor_name
FROM
oms_payable_bill t1
left join project_order_info t2 on t1.order_code=t2.order_code
left join project_info t3 on t2.project_id=t3.id
left join oms_vendor_info t4 on t1.vendor_code=t4.vendor_code
</sql>
<select id="selectOmsPayableBillList" parameterType="OmsPayableBill" resultMap="OmsPayableBillResult">
<include refid="selectOmsPayableBillVo"/>
<include refid="selectOmsPayableBillRelationVo"/>
<where>
<if test="payableBillCode != null and payableBillCode != ''"> and payable_bill_code like concat( #{payableBillCode},'%') </if>
<if test="estimatedPaymentTime != null "> and estimated_payment_time = #{estimatedPaymentTime}</if>
<if test="vendorCode != null and vendorCode != ''"> and vendor_code = #{vendorCode}</if>
<if test="orderCode != null and orderCode != ''"> and order_code like concat( #{orderCode},'%') </if>
<if test="inventoryCode != null and inventoryCode != ''"> and inventory_code like concat( #{inventoryCode},'%') </if>
<if test="productType != null and productType != ''"> and product_type = #{productType}</if>
<if test="totalPriceWithTax != null "> and total_price_with_tax = #{totalPriceWithTax}</if>
<if test="totalPriceWithoutTax != null "> and total_price_without_tax = #{totalPriceWithoutTax}</if>
<if test="taxAmount != null "> and tax_amount = #{taxAmount}</if>
<if test="paymentBillId != null "> and payment_bill_id = #{paymentBillId}</if>
<if test="invoiceReceiptBillId != null "> and invoice_receipt_bill_id = #{invoiceReceiptBillId}</if>
<if test="payableBillCode != null and payableBillCode != ''"> and t1.payable_bill_code like concat( #{payableBillCode},'%') </if>
<if test="estimatedPaymentTime != null "> and t1.estimated_payment_time = #{estimatedPaymentTime}</if>
<if test="vendorCode != null and vendorCode != ''"> and t1.vendor_code = #{vendorCode}</if>
<if test="vendorName != null and vendorName != ''"> and t4.vendor_name = #{vendorName}</if>
<if test="projectCode != null and projectCode != ''"> and t3.project_code = #{projectCode}</if>
<if test="projectName != null and projectName != ''"> and t3.project_name = #{projectName}</if>
<if test="orderCode != null and orderCode != ''"> and t1.order_code like concat( #{orderCode},'%') </if>
<if test="inventoryCode != null and inventoryCode != ''"> and t1.inventory_code like concat( #{inventoryCode},'%') </if>
<if test="productType != null and productType != ''"> and t1.product_type = #{productType}</if>
<if test="totalPriceWithTax != null "> and t1.total_price_with_tax = #{totalPriceWithTax}</if>
<if test="totalPriceWithoutTax != null "> and t1.total_price_without_tax = #{totalPriceWithoutTax}</if>
<if test="taxAmount != null "> and t1.tax_amount = #{taxAmount}</if>
<if test="createTimeStart != null or createTimeEnd != null">
<choose>
<when test="createTimeStart != null and createTimeEnd != null">
and t1.create_time between #{createTimeStart} and #{createTimeEnd}
</when>
<when test="createTimeStart != null">
and t1.create_time <![CDATA[ >= ]]> #{createTimeStart}
</when>
<when test="createTimeEnd != null">
and t1.create_time <![CDATA[ <= ]]> #{createTimeEnd}
</when>
</choose>
</if>
</where>
</select>
@ -68,8 +108,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="totalPriceWithTax != null">total_price_with_tax,</if>
<if test="totalPriceWithoutTax != null">total_price_without_tax,</if>
<if test="taxAmount != null">tax_amount,</if>
<if test="paymentBillId != null">payment_bill_id,</if>
<if test="invoiceReceiptBillId != null">invoice_receipt_bill_id,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
@ -87,8 +127,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="totalPriceWithTax != null">#{totalPriceWithTax},</if>
<if test="totalPriceWithoutTax != null">#{totalPriceWithoutTax},</if>
<if test="taxAmount != null">#{taxAmount},</if>
<if test="paymentBillId != null">#{paymentBillId},</if>
<if test="invoiceReceiptBillId != null">#{invoiceReceiptBillId},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
@ -110,8 +150,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="totalPriceWithTax != null">total_price_with_tax = #{totalPriceWithTax},</if>
<if test="totalPriceWithoutTax != null">total_price_without_tax = #{totalPriceWithoutTax},</if>
<if test="taxAmount != null">tax_amount = #{taxAmount},</if>
<if test="paymentBillId != null">payment_bill_id = #{paymentBillId},</if>
<if test="invoiceReceiptBillId != null">invoice_receipt_bill_id = #{invoiceReceiptBillId},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>

View File

@ -94,6 +94,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{item}
</foreach>
</select>
<select id="listByDeliveryId" resultType="com.ruoyi.sip.domain.InventoryInfo">
<include refid="selectInventoryInfoVo"/>
where t1.product_sn in (
select product_sn from oms_inventory_delivery_detail where delivery_id = #{id}
)
</select>
<insert id="insertInventoryInfo" parameterType="InventoryInfo" useGeneratedKeys="true" keyProperty="id">

View File

@ -153,6 +153,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select product_code from oms_inventory_outer where id=8)
</select>
<select id="selectOutPriceByCode" resultType="java.math.BigDecimal">
SELECT t3.price
FROM oms_inventory_outer t2
INNER JOIN project_order_info t4 ON t2.order_code = t4.order_code
INNER JOIN project_product_info t3
ON (t2.product_code = t3.product_bom_code AND t3.project_id = t4.project_id)
where t2.outer_code = #{outerCode}
</select>
<insert id="insertInventoryOuter" parameterType="InventoryOuter" useGeneratedKeys="true" keyProperty="id">
insert into oms_inventory_outer

View File

@ -59,6 +59,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectVendorInfoVo"/>
where t1.vendor_id = #{vendorId}
</select>
<select id="selectVendorInfoByVendorCode" resultType="com.ruoyi.sip.domain.VendorInfo">
<include refid="selectVendorInfoVo"/>
where t1.vendor_code = #{vendorCode}
</select>
<insert id="insertVendorInfo" parameterType="VendorInfo">
insert into oms_vendor_info