仓储服务-采购业务

news2024/11/25 7:37:24

在这里插入图片描述

1.合并采购需求

请求参数

{
  purchaseId: 1, //整单id
  items:[1,2,3,4] //合并项集合
}

(1) 合并时如果未选择合并的采购单,则先新建采购单然后合并到新建的采购单
在这里插入图片描述
新建的采购单,可以手动给采购单分配人员
在这里插入图片描述

(2)合并时选中了采购单就直接合并
在这里插入图片描述
(3)合并之后设置采购单id并且设置状态为已分配
在这里插入图片描述

合并成功采购单状态无需更改
在这里插入图片描述

/**
     * 合并采购需求/ware/purchase/merge
     * {
     *   purchaseId: 1, //整单id
     *   items:[1,2,3,4] //合并项集合
     * }
     */
    @Transactional
    @Override
    public void mergePurchase(MergeVo mergeVo) {
        //purchaseId不存在(未选择采购单),则自动创建新采购单进行合并,purchaseId存在,则直接赋值即可,并修改状态 (新建 -> 已分配)
        Long purchaseId = mergeVo.getPurchaseId();
        if (mergeVo.getPurchaseId() == null){
            //创建新采购单
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setCreateTime(new Date());
            purchaseEntity.setUpdateTime(new Date());
            //设置状态为:新建
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATE.getCode());
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }

        //TODO 正在采购中的采购需求不能进行合并,确认采购单是0或1才可以合并
        //purchaseId存在(已选择采购单),则直接赋值即可,并修改状态 (新建 -> 已分配)
        Long finalPurchaseId = purchaseId;//拿到采购单Id
        List<PurchaseDetailEntity> collect = mergeVo.getItems().stream().filter(item -> {
            //筛选出状态为新建的采购需求的item
            PurchaseDetailEntity purchaseDetailEntity = purchaseDetailDao.selectById(item);
            return purchaseDetailEntity.getStatus() == WareConstant.PurchaseDetailStatusEnum.CREATE.getCode();
        }).map(item -> {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            purchaseDetailEntity.setId(item);
            //更新采购单id
            purchaseDetailEntity.setPurchaseId(finalPurchaseId);
            //更新状态为已分配
            purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());
            return purchaseDetailEntity;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(collect);
    }

2.领取采购单

请求参数

[1,2,3,4]//采购单id

(1)筛选出采购单状态为 新建或者已领取的采购单
在这里插入图片描述
(2)修改采购单状态为 已领取
在这里插入图片描述
(3)根据采购单id查出采购需求,修改采购需求的状态为正在采购
在这里插入图片描述

/**
     * 领取采购单
     * [1,2,3,4]//采购单id
     */
    @Transactional
    @Override
    public void received(List<Long> ids) {
        //1.修改采购单
        List<PurchaseEntity> collect = ids.stream().map(id -> {
            PurchaseEntity purchaseEntity = this.getById(id);
            return purchaseEntity;
        }).filter(purchaseEntity -> {
            //筛选出采购单状态为 新建或者已领取的采购单
            if (purchaseEntity.getStatus() == WareConstant.PurchaseStatusEnum.CREATE.getCode()
                    || purchaseEntity.getStatus() == WareConstant.PurchaseStatusEnum.ASSIGNED.getCode()) {
                return true;
            }
            return false;
        }).map(purchaseEntity -> {
            //修改采购单状态为 已领取
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode());
            purchaseEntity.setUpdateTime(new Date());
            return purchaseEntity;
        }).collect(Collectors.toList());
        //修改采购单
        this.updateBatchById(collect);

        /**
         * 需要转换list集合时使用steam流,只需要去list集合中的元素使用增强for即可
         */
        //2.修改采购需求
        collect.forEach(item -> {
            //根据采购单id查出采购需求
            List<PurchaseDetailEntity> list = purchaseDetailService.queryByPurchaseIds(item.getId());
            //修改采购需求的状态为正在采购
            List<PurchaseDetailEntity> detailEntities = list.stream().map(purchaseDetailEntity -> {
                PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
                detailEntity.setId(purchaseDetailEntity.getId());
                detailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.BUYING.getCode());
                return detailEntity;
            }).collect(Collectors.toList());
            //修改采购需求
            purchaseDetailService.updateBatchById(detailEntities);
        });
    }

3.完成采购

请求参数

{
	"id":5,
	"items":[
		{"itemId":5,"status":4,"reason":""}
		,{"itemId":6,"status":3,"reason":"缺货"}
		]
}

(1)只要采购需求全部都完成,才可以修改采购单的状态为 已完成,否则是 有异常

在这里插入图片描述
在这里插入图片描述
(2)采购需求全部完成则设置采购单状态为已完成
请求参数

{
	"id":5,
	"items":[
		{"itemId":5,"status":3,"reason":""}
		,{"itemId":6,"status":3,"reason":""}
		]
}

在这里插入图片描述
在这里插入图片描述

//完成采购
    @Transactional
    @Override
    public void done(PurchaseDoneVo purchaseDoneVo) throws Exception {
        /**
         * {
         *    id: 123,//采购单id
         *    items: [ {itemId:1,status:3,reason:""},{itemId:2,status:4,reason:"无货"} ] // reason:完成/失败的需求详情
         *
         * }
         */
        //只要采购需求全部都完成,才可以修改采购单的状态为 已完成,否则是 有异常
        Long id = purchaseDoneVo.getId();
        Boolean flag = true;
        List<PurchaseItemDoneVo> items = purchaseDoneVo.getItems();
        //遍历 采购需求
        List<PurchaseDetailEntity> detailEntityList = new ArrayList<>();
        for (PurchaseItemDoneVo item : items) {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            //只要采购需求的状态 != 采购失败 就是 已完成
            if (item.getStatus() == WareConstant.PurchaseDetailStatusEnum.HASERROR.getCode()){
                purchaseDetailEntity.setStatus(item.getStatus());
                flag = false;
            }else {
                //此条采购需求完成
                purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.FINISH.getCode());
                //将成功采购的入库
                PurchaseDetailEntity detailEntity = purchaseDetailService.getById(item.getItemId());
                //传入 商品id、仓库id、商品数量
                wareSkuService.addStock(detailEntity.getSkuId(),detailEntity.getWareId(),detailEntity.getSkuNum());
            }
            purchaseDetailEntity.setId(item.getItemId());
            purchaseDetailEntity.setPurchaseId(id);
            detailEntityList.add(purchaseDetailEntity);
        }
        //批量更新 采购需求
        purchaseDetailService.updateBatchById(detailEntityList);

        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(id);
        purchaseEntity.setUpdateTime(new Date());
        purchaseEntity.setStatus(flag?WareConstant.PurchaseStatusEnum.FINISH.getCode() : WareConstant.PurchaseStatusEnum.HASERROR.getCode());
        this.updateById(purchaseEntity);


    }

4.商品入库

(1)将采购需求中完成的需求进行入库,入库参数:商品id、仓库id、商品数量,商品名称从gulimall-product服务查出
在这里插入图片描述

 @Override
    public void addStock(Long skuId, Long wareId, Integer skuNum) throws Exception {
        List<WareSkuEntity> wareSkuEntities = wareSkuDao.selectList(new QueryWrapper<WareSkuEntity>().eq("sku_id", skuId).eq("ware_id", wareId));
        if (wareSkuEntities == null || wareSkuEntities.size() == 0) {
            WareSkuEntity wareSkuEntity = new WareSkuEntity();
            wareSkuEntity.setSkuId(skuId);
            wareSkuEntity.setWareId(wareId);
            wareSkuEntity.setStock(skuNum);
            //锁定库存
            wareSkuEntity.setStockLocked(0);
            //远程查询商品名称
            //TODO 1.自己处理异常,查询名称错误不影响整个入库操作
            // 2.向上抛出异常,外层接收异常并回滚
            // 3.还有什么方法出现异常不回滚
            try {
                R r = productFeignService.info(skuId);
                if (r.getCode() == 0){
                    //LinkedHashMap无法转换实体类,类型转换异常
                    /**
                     * 远程传参和接收参数时一定要指定泛型!!!!!
                     *
                     * 因为rpc远程调用在底层还是使用的HTTPClient
                     * 所以在传递参数的时候,必定要有个顺序,当你传递map的时候map里面的值也要有顺序,
                     * 不然服务层在接的时候就出问题了,所以它才会从map转为linkedhashMap
                     * !spring 有一个类叫ModelMap,继承了linkedhashMap public class ModelMap extends LinkedHashMap ,
                     * 所以一个接口返回的结果就可以直接用ModelMap来接,注意ModelMap是没有泛型的,不管你返回的结果是什么类型的map,
                     * 泛型是多复杂的map,都可以直接new一个Modelmap,用它来接返回的结果
                     */
//                    Map<String,Object> map = (Map<String, Object>) r.get("skuInfo");
//                    String skuName = (String) map.get("skuName");
//                    wareSkuEntity.setSkuName(skuName);

                    Object obj = r.get("skuInfo");
                    ObjectMapper objectMapper = new ObjectMapper();
                    SkuInfoEntity skuInfoEntity = objectMapper.convertValue(obj, SkuInfoEntity.class);
                    wareSkuEntity.setSkuName(skuInfoEntity.getSkuName());
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new Exception();
            }
            wareSkuDao.insert(wareSkuEntity);
        } else {
            wareSkuDao.addStock(skuId, wareId, skuNum);
        }
    }

5.遇到问题:

使用feign调用远程服务时,会出现feign返回值LinkedHashMap无法转换实体类异常,因为feign使用的httpClient是用LinkedHashMap封装数据的,所以无法直接强转,可以直接从LinkedHashMap中取值使用,或者使用ObjectMapper转换类型
(1)

ObjectMapper objectMapper = new ObjectMapper();
XxxEntity xxx = objectMapper.convertValue(feign返回的实体类型,需要转换的类型);

(2)
或者使用工具类进行序列化->反序列化操作,与上面操作相似原文链接
这里r会r.get(“data”),实战中根据需求修改

XxxEntity xxx = FeignUtil.formatClass(R r, Class<T> tClass)
import com.google.common.base.Strings;
import com.leicx.guli.common.exception.RRException;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * @author daxiong
 * @date 2021/8/16 下午10:15
 */
public class FeignUtil {
 
    public static <T> T formatClass(R r, Class<T> tClass) {
        String jsonString = getResultJson(r);
        if (Strings.isNullOrEmpty(jsonString)) {
            return null;
        }
        return JsonUtil.parseObject(jsonString, tClass);
    }
 
    private static String getResultJson(R r) {
        if (!r.success()) {
            throw new RRException(r.get("msg").toString());
        }
        return JsonUtil.toJsonString(r.get("data"));
    }
 
    public static <T> List<T> formatListClass(R r, Class<T> tClass) {
        String jsonString = getResultJson(r);
        if (Strings.isNullOrEmpty(jsonString)) {
            return new ArrayList<>();
        }
        return JsonUtil.parseList(jsonString, tClass);
    }
}
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
 
import java.io.IOException;
import java.util.List;
 
/**
 * @author daxiong
 * @date 2021/8/16 下午10:12
 */
@Slf4j
public class JsonUtil {
 
    static final ObjectMapper objectMapper = new ObjectMapper();
 
    public static <T> T parseObject(String jsonStr, Class<T> tClass) {
        try {
            return objectMapper.readValue(jsonStr, tClass);
        } catch (IOException e) {
            log.error(e.getMessage());
            return null;
        }
    }
 
    public static <T> List<T> parseList(String text, Class<T> clazz) {
        JavaType javaType = objectMapper.getTypeFactory().constructCollectionType(List.class, clazz);
        try {
            return objectMapper.readValue(text, javaType);
        } catch (IOException e) {
            log.error(e.getMessage());
            return null;
        }
    }
 
    /**
     * json序列化
     *
     * @param obj 需要序列化的对象
     * @return
     */
    public static String toJsonString(Object obj) {
        try {
 
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error(e.getMessage());
            return null;
        }
    }
 
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/571331.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linuxOPS基础_运维概述,及其泛概念

运维岗位定义 什么是运维&#xff1f; ​ 在技术人员&#xff08;写代码的&#xff09;之间&#xff0c;一致对运维有一个开玩笑的认知&#xff1a;运维就是修电脑的、装网线的、背锅的岗位。 ​ IT运维管理是指为了保障企业IT系统及网络的可用性、安全性、稳定性&#xff0…

学习go的操作(本人已有c的基础,请思考后再看)

建立一个文件&#xff08;我的第一个文件是hellow.go&#xff09;&#xff0c;后在终端执行一下几步&#xff1a;我用的是go build先编译成了可执行文件&#xff08;.exe&#xff09;【1.go build hellow.go 2.hellow.exe】。当然&#xff0c;你也可以用go run直接运行【…

【c语言习题】函数递归调用实现汉诺塔

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c语言系列专栏&#xff1a;c语言之路重点知识整合 &#x…

stable-diffusion安装controlnet插件

1、通过url安装controlnet插件 1&#xff09;extensions → install from URL → install 然后填入&#xff1a;https://github.com/Mikubill/sd-webui-controlnet 2&#xff09;installed → apply and restart UI 2、下载模型 下载controlnet模型&#xff08;50G左右&#…

chatgpt赋能python:Python交互:让你的编程更高效

Python 交互&#xff1a;让你的编程更高效 Python 是一门功能强大的编程语言&#xff0c;拥有大量的第三方库、工具和框架&#xff0c;能够帮助开发者实现各种各样的功能和应用。在 Python 编程中&#xff0c;交互&#xff08;Interactive&#xff09;模式是一种非常重要的工具…

探索基于人工智能的手机在网时长风险评估

引言 在当今竞争激烈的商业环境中&#xff0c;企业面临着不断增长的风险和挑战。为了保持竞争优势和提供优质的用户体验&#xff0c;企业需要能够准确评估用户的风险&#xff0c;并提供个性化的服务来满足不同用户的需求。 本文将介绍如何结合手机在网时长、手机在网状态和手…

Flutter控件之CircularProgressIndicator

CircularProgressIndicator的作用 Flutter中的CircularProgressIndicator是一个圆形进度指示器&#xff0c;用于表示正在进行的任务的进度。它通常用于长时间运行的任务&#xff0c;例如文件下载、网络请求等。CircularProgressIndicator可以在圆周上旋转&#xff0c;以表示正…

丽江“美丽县城”建设,高精度地籍免像控案例分享

一、项目背景 云南省地矿测绘院于2020年6月承接丽江市玉龙县“美丽县城”建设项目1&#xff1a;500倾斜摄影及地形图测绘项目。项目要求对玉龙县城区及其周边等约30平方公里区域进行优于3CM倾斜摄影测量。 并基于三维模型完成地形高程点、地貌、地物特征点的采集成图&#xf…

leetcode203. 移除链表元素

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【LeetCode】 &#x1f353;希望我们一起努力、成长&#xff0c;共同进步。 题目链接 给你一个链表的头节点 head 和一个整数 val &…

Docker安装OpenWrt

我笔记本MacOs安装Docker OpenWrt 失败了,网络一直容器内外无法访问. 今天使用虚拟机安装一下,虚拟机使用Parallels,系统使用kali 一、安装docker sudo apt install docker.io 二、把网卡混杂模式打开 根据您当前的ip查看网卡&#xff01;&#xff01;&#xff01; 在您的liu…

如何在华为OD机试中获得满分?Java实现【数组的中心位置】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

【C++】STL中stack的用法及模拟实现

目录 一、stack的简介二、stack的使用三、stack的模拟实现 一、stack的简介 stack是一种容器适配器&#xff0c;专门用在后进先出操作的上下文中环境中&#xff0c;其中的元素只允许从容器固定的一端进行插入和删除操作。stack是作为容器适配器来实现的&#xff0c;容器适配器…

市值蒸发21亿港元,王一博还能拉着乐华走多久?

5月22日&#xff0c;#乐华被冻结2390万财产#话题冲上热搜。 近日&#xff0c;头顶“王一博”光环的乐华娱乐集团&#xff08;下称“乐华娱乐”&#xff0c;02306.HK&#xff09;交出了上市后的首份财报。 4月25日&#xff0c;财报公布的首个交易日&#xff0c;其股价下跌2.06…

【iOS】【最新】2023苹果开发者账号注册流程(公司类型)

一 Apple Developer 申请开发者账号 Apple Developer 点击 Account 创建 Apple ID 最好新注册一个新的&#xff0c;专门用做开发。 需要注意的是 开发者的名字和 ID 想好在填写 &#xff0c;注册成功后&#xff0c;不能自己修改&#xff0c;需要修改的话只能联系苹果客服。…

CCF-CSP 201903-1 小中大

该题比较简单&#xff0c;因为所给数据都是排好序的了&#xff0c;对于最大值与最小值我们只需判断第一个元素与最后一个元素的关系即可&#xff0c;而中位数的判断则与n的大小有关&#xff0c;如果n为偶数&#xff08;下标从1开始&#xff09;&#xff0c;那么中间会存在两个数…

各个查询引擎是如何提高写入效率,查询效率

RocketMq 1. 顺序IO 如果消息生产者生产了消息&#xff0c;发送到broker之后&#xff0c;需要存储在磁盘中&#xff0c;如果直接存储到话&#xff0c;并发度会很小&#xff0c;因为操作磁盘会很慢&#xff0c;尤其是操作随机IO&#xff0c;因此看看能不能在写入磁盘的时候&am…

制造企业如何抓住2023经济复苏做好数字化转型

2022年&#xff0c;在地缘政治冲突、新冠疫情、供应链挑战、通胀压力等多重冲击下&#xff0c;中国经济迎难而进。2023年随着防疫政策的调整和优化&#xff0c;也将成为经济全面复苏和发展的重要一年&#xff0c;这对于制造企业来说是一个重要的机遇。 据国际数据公司IDC预测&a…

尚硅谷Docker实战教程-笔记01【理念简介、官网介绍、平台入门图解、平台架构图解】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷Docker实战教程&#xff08;docker教程天花板&#xff09;_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01【理念简介、官网介绍、平台入门图解、平台架构图解】尚硅谷Docker实战教程-笔…

Java | 一分钟掌握定时任务 | 9 - PowerJob分布式定时任务

作者&#xff1a;Mars酱 声明&#xff1a;本文章由Mars酱整理编写&#xff0c;部分内容来源于网络&#xff0c;如有疑问请联系本人。 转载&#xff1a;欢迎转载&#xff0c;转载前先请联系我&#xff01; 前言 我们选择一套框架或者技术的时候&#xff0c;一定要知道它的特点和…

电源大师课-初阶

第一课 电源系统构成和基础原理 1-电源效率 总的Pout除以Pin 2-输出电压调整率 源调整率(输入电压变化时&#xff0c;输出稳定程度) 负载调整率(输出负载变化时&#xff0c;输出稳定度) 温度调整率(工作环境温度在极限情况下&#xff0c;输出的稳定度) 3-纹波测试(20MHz、最…