package com.topsun.posclient.sales.core; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import com.topsun.posclient.common.AppConstants; import com.topsun.posclient.common.POSClientApp; import com.topsun.posclient.common.POSException; import com.topsun.posclient.common.ProjectUtil; import com.topsun.posclient.common.service.IBaseService; import com.topsun.posclient.common.service.impl.BaseServiceImpl; import com.topsun.posclient.datamodel.CardRule; import com.topsun.posclient.datamodel.CashierModel; import com.topsun.posclient.datamodel.Item; import com.topsun.posclient.datamodel.OldGold; import com.topsun.posclient.datamodel.PartSales; import com.topsun.posclient.datamodel.Retail; import com.topsun.posclient.datamodel.RetailFP; import com.topsun.posclient.datamodel.RetailM; import com.topsun.posclient.datamodel.RetailMP; import com.topsun.posclient.datamodel.RetailP; import com.topsun.posclient.datamodel.UnSalePart; import com.topsun.posclient.webservice.dto.RetailE; import com.topsun.posclient.webservice.dto.Retail_Fp; import com.topsun.posclient.webservice.dto.Retail_M; import com.topsun.posclient.webservice.dto.Retail_MPI; import com.topsun.posclient.webservice.dto.Retail_P; /** * 零售数据工具类,处理零售数据金额相关计算,零售明细拆分等 * * @author Dong * */ public class SalesDataUtil { static IBaseService baseService = new BaseServiceImpl(); /** * 从PartSales零售信息中获取基础的Retail信息,不含旧金、断料、明细等数据 * @param partSales 销售信息 * @return * @throws POSException */ public static Retail getRetailFromPartSales(PartSales partSales) throws POSException{ Retail retail = new Retail(); retail.setID(1); if(null != partSales.getVipUser() && null != partSales.getVipUser().getCardNo()){ retail.setCardNo(partSales.getVipUser().getCardNo());//零售界面的会员卡号 }else{ retail.setCardNo(""); } retail.setCashierID(POSClientApp.get().getLoginUser().getId()); if(partSales.isMlimit()){//抹零 retail.setDiscountAccount(POSClientApp.get().getLoginUser().getId()); retail.setDiscountToZero(partSales.getDiscountToZero()); }else{ retail.setDiscountAccount(0); retail.setDiscountToZero(new BigDecimal(0)); } if(partSales.isMratio()){//折扣 retail.setDiscountAmount(partSales.getDiscountAmount()); retail.setDiscountRate(partSales.getDiscountRate()); }else{ retail.setDiscountAmount(new BigDecimal(0)); retail.setDiscountAmount_M(new BigDecimal(0)); retail.setDiscountRate(new BigDecimal(0)); } retail.setDiscount(SalesDataUtil.calculateDiscountAmountTotal(partSales));//优惠总金额 retail.setDocNum(partSales.getDocNum());//单据编号,去零售界面的单据编号 if(null != partSales.getVipUser() && null != partSales.getVipUser().getPoint()){ retail.setEnablePoint(partSales.getVipUser().getPoint().intValue()); BigDecimal discountAmountMCount = calculateDiscountAmountM(partSales); retail.setDiscountAmount_M(discountAmountMCount);//会员折扣合计 retail.setMemberDiscount(calculateMemberDiscount(partSales));//会员折扣率 }else{ retail.setEnablePoint(0);//零售界面会员可用积分 } retail.setInvoceAmount(partSales.getFactTotalAmount());//开票金额 retail.setIsMember(partSales.isVip()==true?1:0);//是否会员销售 retail.setIsReplace(partSales.getIsReplace());//是否旧金贴换 retail.setIsReturn(partSales.getIsReturn());//是否退货 retail.setReceivable(SalesDataUtil.calculateSalesAmountTotal(partSales));//打折前金额累计(不打折,不促销,不抹零,不店长折扣) retail.setSalesDate(partSales.getSalesDate());//界面的销售日期 retail.setSalesType(String.valueOf(partSales.getSalesType()));//销售类型 retail.setShopID(Integer.valueOf(POSClientApp.get().getSysConfig().getOwnerShop())); retail.setTotals(partSales.getFactTotalAmount());//实收总金额 if(partSales.getSalesType() == AppConstants.SALES_TYPE_GOLDBACK){ BigDecimal totalSales = new BigDecimal(0); for(Item iii : partSales.getItemList()){ totalSales = totalSales.add(iii.getFactAmount()); } retail.setTotalSales(totalSales);//销售总金额(应售总金额) }else{ retail.setTotalSales(partSales.getFactTotalAmount());//销售总金额(应售总金额) } retail.setUsePoint(partSales.getUsePoint());//本次使用积分,结算方式为积分的情况使用的积分 retail.setSourceNum(partSales.getSourceNum()); retail.setIsReplace(partSales.getIsReplace()); retail.setIsReturn(partSales.getIsReturn()); retail.setRetailFPList(partSales.getRetailFPList());//设置发票信息 retail.setOldDocNum(partSales.getOldDocNum());//设置原始单据号码 return retail; } /** * 根据PartSales销售信息获取零售明细数据 * @param partSales 销售数据 * @return */ public static List<RetailM> getRetailMsFromPartSales(PartSales partSales){ List<Item> itemList = partSales.getItemList(); if(null == itemList || itemList.size() == 0){ return null; } List<RetailM> retailMList = new ArrayList<RetailM>(); List<Item> newList = new ArrayList<Item>(); for(int i=0; i<itemList.size(); i++){ //旧金不放在RetailM集合中,有单据的旧金数据集合 if(itemList.get(i).getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ continue; }else{ newList.add(itemList.get(i)); } } for(int i=0; i<newList.size(); i++){ retailMList.add(convertItemToRetailM(newList.get(i), partSales, i+1)); } return retailMList; } /** * 将零售明细集合转换成单品集合 * @param retailMs * @return * @throws Exception * @throws POSException */ public static List<Item> convertRetailEToItemList(RetailE retailE, String docNum) throws POSException, Exception{ List<Item> itemList = new ArrayList<Item>(); Retail_M[] retailMArray = retailE.getRetail_Ms().getRetail_M(); for(int i=0; i<retailMArray.length; i++){ Retail_M rm = retailMArray[i]; Item item = new Item(); item.setDocNum(docNum);//单据编号,去零售界面的单据编号 item.setId(rm.getItemID()); item.setItemCode(rm.getItemCode()); item.setItemName(baseService.getItemNameById(rm.getItemID())); item.setItemStatus(rm.getItemType()); item.setMatkl(rm.getMatkl()); item.setMATNR(rm.getMATNR()); item.setMatrnName(baseService.getMaterialByMatnr(rm.getMATNR()).getMaktx()); item.setSalesAmount(rm.getSalesAmount()); item.setFactAmount(rm.getFactAmount()); item.setZMDLSBQJ(rm.getPrice_G()); item.setZJGF(rm.getProcessFee()); item.setFactZJGF(rm.getProcessFee_S()); item.setZDPZL(rm.getSalesWeight()); item.setItemCode(rm.getItemCode()); item.setZDPYZL(rm.getWeight()); item.setItemType(AppConstants.ITEM_TYPE_TIMELESS); item.setItemStatus(AppConstants.ITEM_STATU_GOLD_TIMEOUT); item.setOldDocNum(docNum);//设置原始单据号 itemList.add(item); } return itemList; } /** * 将单品对象转换成零售明细数据 * @param item * @param docNum * @return */ public static RetailM convertItemToRetailM(Item item, PartSales partSales, int index){ RetailM retailM = new RetailM(); retailM.setOldAmount(getOldAmountForItem(item, index-1, partSales));//设置旧金抵扣金额 retailM.setReplaceAmount(getReplaceAmountForItem(item, partSales));//设置换货抵扣金额 retailM.setInvoiceCode(item.getInvoceCode());//设置发票号码 retailM.setInvoiceNumber(item.getInvoceNumber()); retailM.setDocNum(partSales.getDocNum());//单据编号,去零售界面的单据编号 if(item.getCashierName() != null && !"".equals(item.getCashierName())){ retailM.setEmployeeID(Integer.valueOf(item.getCashierName())); } retailM.setItemId(item.getId()); retailM.setItemCode(item.getItemCode()); retailM.setItemName(item.getItemName()); retailM.setItemType(item.getItemStatus()); retailM.setMATNR(null == item.getMATNR()?item.getMatkl():item.getMATNR()); retailM.setIsReplace(item.getIsOldGold());//是否旧金贴换 retailM.setSalesAmount(item.getSalesAmount());//打折之前设置应售价为Item单品Grid的应售 retailM.setFactAmount(null == item.getFactAmount()?item.getSalesAmount():item.getFactAmount());//实售价 促销,店长打折后的价格 if(null != item.getUnSalePart()){ retailM.setUnSalesWeight(item.getUnSalePart().getWeight());//截断重量 retailM.setPalAmount(item.getUnSalePart().getPalAccount());//损益金额(断头) retailM.setPalWeight(item.getUnSalePart().getPalWeight());//损益重量(断头) }else{ retailM.setUnSalesWeight(new BigDecimal(0)); retailM.setPalAmount(new BigDecimal(0)); retailM.setPalWeight(new BigDecimal(0)); } retailM.setPointAmount(getPointAmountForItem(partSales, item));//积分抵扣款 BigDecimal payAmount = new BigDecimal(0); payAmount = (null == item.getFactAmount()?item.getSalesAmount():item.getFactAmount()).subtract(retailM.getOldAmount().add(retailM.getReplaceAmount())); payAmount = payAmount.subtract(retailM.getPointAmount());//减去积分抵扣 payAmount = payAmount.setScale(2, BigDecimal.ROUND_HALF_UP); retailM.setPayAmount(payAmount);//实付款=应售款-旧金抵扣金额-换货抵扣金额(基本零售为0) retailM.setPrice_G(null == item.getPrice()?new BigDecimal(0):item.getPrice());//设置实时金价 retailM.setProcessFee(null == item.getZJGF()?new BigDecimal(0):item.getZJGF());//工费 retailM.setProcessFee_S(null == item.getFactZJGF()?retailM.getProcessFee():item.getFactZJGF());//结算工费 如果打折的话按工费*打折系数,断料的话原工费-实际克重*克工费 retailM.setSalesWeight(null == item.getZDPZL()?item.getZDPYZL():item.getZDPZL());//销售重量 retailM.setSourceCode(item.getItemCode());//原单品编码 retailM.setWeight(item.getZDPYZL());//原重量 retailM.setAccountType(item.getZJSHJFS()); retailM.setSettlementPrice(null == item.getFactAmount()?new BigDecimal(0):item.getFactAmount());//结算金价 retailM.setSettlementPrice_G(null == item.getPrice()?item.getZMDLSBQJ():item.getPrice());//结算价 retailM.setMatkl(item.getMatkl());//物料组 retailM.setPromotionID(item.getPromotionId()); retailM.setPromotionName(item.getPromotionName()); if(partSales.getSalesType() == AppConstants.SALES_TYPE_EXECHANGE){ retailM.setInvoiceAmount(new PartSalesPrintData().getPrintInvoiceAmountForExechange(item, partSales, index)); }else{ retailM.setInvoiceAmount(new PartSalesPrintData().getPrintInvoiceAmount(item, partSales, index)); } System.out.println(""); System.out.println("单品["+retailM.getItemName()+"]的开票金额为:"+retailM.getInvoiceAmount()); return retailM; } /** * 计算每个单品的积分抵扣金额 * @param partSales 零售信息 * @param item 单品信息 * @return */ private static BigDecimal getPointAmountForItem(PartSales partSales, Item item){ BigDecimal ret = new BigDecimal(0); if(!partSales.isVip()){ return ret; } if(null == item || null == partSales){ return ret; } if(item.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ return ret; } if(null == partSales.getItemList() || partSales.getItemList().size() == 0){ return ret; } if(partSales.getSalesType() == AppConstants.SALES_TYPE_SALES){//如果是基本零售 BigDecimal amountCount = partSales.getMemberAmount(); BigDecimal totalAmount = calculateFactAmountTotalNoOldGoldAndReturned(partSales); if(totalAmount.compareTo(new BigDecimal(0)) == 0){ return new BigDecimal(0); }else{ BigDecimal point = item.getFactAmount().divide(totalAmount, 4, BigDecimal.ROUND_HALF_UP);//权重 ret = amountCount.multiply(point); } }else{ return new BigDecimal(0); } ret = ret.setScale(2, BigDecimal.ROUND_HALF_UP); return ret; } /** * 获取某个单品的换货抵扣金额 * @param item 单品 * @param partSales 零售信息 * @return */ private static BigDecimal getReplaceAmountForItem(Item item, PartSales partSales){ if(null == item || null == partSales){ return new BigDecimal(0); } if(item.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ return new BigDecimal(0); } if(null == partSales.getItemList() || partSales.getItemList().size() == 0){ return new BigDecimal(0); } if(partSales.getSalesType() == AppConstants.SALES_TYPE_EXECHANGE){//换货 BigDecimal replaceAmountCount = new BigDecimal(0); for(Item iii : partSales.getItemList()){ if(iii.getItemType().equals(AppConstants.ITEM_TYPE_RETURNED)){ replaceAmountCount.add(iii.getFactAmount());//旧金抵扣金额合计 } } BigDecimal totalAmount = calculateFactAmountTotalNoReturned(partSales); BigDecimal point = item.getFactAmount().divide(totalAmount, 4, BigDecimal.ROUND_HALF_UP);//权重 return replaceAmountCount.multiply(point); }else{ return new BigDecimal(0); } } // /** // * 获取某个单品的旧金抵扣金额 // * @param item 单品 // * @param partSales 零售信息 // * @return // */ // @Deprecated // public static BigDecimal getOldAmountForItem(Item item, PartSales partSales){ // if(null == item || null == partSales){ // return new BigDecimal(0); // } // if(item.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ // return new BigDecimal(0); // } // if(null == partSales.getItemList() || partSales.getItemList().size() == 0){ // return new BigDecimal(0); // } // if(partSales.getSalesType() != AppConstants.SALES_TYPE_SALES){//如果是基本零售 // return new BigDecimal(0); // } // //零售数据中的所有旧金金额合计 // BigDecimal oldAmountCount = new BigDecimal(0); // for(Item iii : partSales.getItemList()){ // if(iii.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ // oldAmountCount = oldAmountCount.add(iii.getFactAmount());//旧金抵扣金额合计 // } // } // //没有旧金的合计 // BigDecimal totalAmount = calculateFactAmountTotalNoOldGoldAndReturned(partSales); // if(totalAmount.compareTo(new BigDecimal(0)) == 0){ // return new BigDecimal(0); // } // BigDecimal point = item.getFactAmount().divide(totalAmount, 4, BigDecimal.ROUND_HALF_UP);//权重 // return oldAmountCount.multiply(point); // } //start add by tandong at 2014 03 09 最新权重算法获取旧金抵扣金额 /** * 根据新的权重计算法获取单品的旧金抵扣金额 * @param item 单品 * @param itemIndex 单品索引,用于区分是否为最后一个单品 * @param partSales 零售数据 * @return 旧金抵扣 */ public static BigDecimal getOldAmountForItem(Item item, int itemIndex, PartSales partSales){ if(null == item || null == partSales){ return new BigDecimal(0); } if(item.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ return new BigDecimal(0); } if(null == partSales.getItemList() || partSales.getItemList().size() == 0){ return new BigDecimal(0); } if(partSales.getSalesType() != AppConstants.SALES_TYPE_SALES){//如果是基本零售 return new BigDecimal(0); } if(item.isChaiPiao() && item.getFactAmount().compareTo(new BigDecimal(100000)) == 0){//如果item被拆票,并且金额=10W return new BigDecimal(0); } //零售数据中的所有旧金金额合计 BigDecimal oldAmountCount = new BigDecimal(0); for(Item iii : partSales.getItemList()){ if(iii.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ oldAmountCount = oldAmountCount.add(iii.getFactAmount());//旧金抵扣金额合计 } } //没有旧金的合计 System.out.println(); System.out.println("CountAmount: "+partSales.getCountAmount()); BigDecimal totalAmount = calculateFactAmountTotalNoOldGoldAndReturned(partSales); //如果在计算旧金抵扣之前整单有抹零金额,则在抹零的时候已经修改了单品item的factAmount,这里需要再合计金额中也减去 //整单的抹零金额来保证后面权重的正确性 if(partSales.getDiscountToZero().compareTo(new BigDecimal(0)) == 1){ totalAmount = totalAmount.subtract(partSales.getDiscountToZero()); } //如果在计算旧金抵扣之前整单有店长折扣金额,则在抹零的时候已经修改了单品item的factAmount,这里需要再合计金额中也减去 //整单的折扣金额来保证后面权重的正确性 if(partSales.getDiscountAmount().compareTo(new BigDecimal(0)) == 1){ totalAmount = totalAmount.subtract(partSales.getDiscountAmount()); } System.out.println("totalAmount: "+totalAmount); if(totalAmount.compareTo(new BigDecimal(0)) == 0){ return new BigDecimal(0); } List<Item> newList = new ArrayList<Item>(); for(Item iii : partSales.getItemList()){ if(iii.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ continue; } newList.add(iii); } //如果是最后一个单品 if(itemIndex == newList.size() - 1){ BigDecimal ret = new BigDecimal(0); BigDecimal oldGoldAdd = new BigDecimal(0); for(Item i : newList){ if(i.getItemCode().equals(item.getItemCode()) && i.getId() == i.getId()){ System.out.println("最后一个单品"); System.out.println(item.getItemCode() +" 实售金额为:"+item.getFactAmount()+" 总金额为:"+totalAmount); ret = oldAmountCount.subtract(oldGoldAdd); }else{ BigDecimal dkAmount = oldAmountCount.multiply(i.getFactAmount()).divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP);//权重; // dkAmount = dkAmount.setScale(2, BigDecimal.ROUND_HALF_UP); oldGoldAdd = oldGoldAdd.add(dkAmount); } } System.out.println(item.getItemCode() +" 前面单品的旧金抵扣累计为:"+oldGoldAdd); System.out.println(item.getItemCode() +" 总的旧金金额为:"+oldAmountCount); System.out.println(item.getItemCode() +" 旧金抵扣为:"+ret); System.out.println(); System.out.println(); return ret; }else{//不是最后一个单品直接乘以权重比列得出抵扣金额 BigDecimal dkAmount = oldAmountCount.multiply(item.getFactAmount()).divide(totalAmount, 4, BigDecimal.ROUND_HALF_UP);//权重 dkAmount = dkAmount.setScale(2, BigDecimal.ROUND_HALF_UP); System.out.println(item.getItemCode() +" 实售金额为:"+item.getFactAmount()+" 总金额为:"+totalAmount); System.out.println(item.getItemCode() +" 总的旧金金额为:"+oldAmountCount); System.out.println(item.getItemCode() +" 旧金抵扣为:"+dkAmount); System.out.println(); System.out.println(); return dkAmount; } } //end add by tandong at 2014 03 09 最新权重算法获取旧金抵扣金额 /** * 获取整单的旧金抵扣金额 * @param item 单品 * @param partSales 零售信息 * @return */ public static BigDecimal getOldAmount(PartSales partSales){ if(null == partSales){ return new BigDecimal(0); } if(null == partSales.getItemList() || partSales.getItemList().size() == 0){ return new BigDecimal(0); } if(partSales.getSalesType() == AppConstants.SALES_TYPE_SALES){//如果是基本零售 BigDecimal oldAmountCount = new BigDecimal(0); for(Item iii : partSales.getItemList()){ if(iii.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ oldAmountCount = oldAmountCount.add(iii.getFactAmount());//旧金抵扣金额合计 } } return oldAmountCount; }else{ return new BigDecimal(0); } } /** * 获取整单中被拆票的单品的旧金抵扣金额 * @param item 单品 * @param partSales 零售信息 * @return */ public static BigDecimal getOldAmountForCPItem(Item item,PartSales partSales){ if(null == partSales){ return new BigDecimal(0); } if(null == partSales.getItemList() || partSales.getItemList().size() == 0){ return new BigDecimal(0); } if(partSales.getSalesType() == AppConstants.SALES_TYPE_SALES){//如果是基本零售 BigDecimal oldAmountCount = new BigDecimal(0); for(Item iii : partSales.getItemList()){ if(iii.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ oldAmountCount = oldAmountCount.add(iii.getFactAmount());//旧金抵扣金额合计 } } BigDecimal totalAmount = calculateFactAmountTotalNoOldGoldAndReturned(partSales); if(totalAmount.compareTo(new BigDecimal(0)) == 0){ return new BigDecimal(0); }else{ //计算被拆票的Item实收合计,即是拆票之前单品的实售 BigDecimal cpItemAmountCount = new BigDecimal(0); for(Item ii : partSales.getItemList()){ if(ii.isChaiPiao() && ii.getItemCode().equals(item.getItemCode())){ cpItemAmountCount = cpItemAmountCount.add(ii.getFactAmount()); } } //计算拆票之前单品实售在整单合计中的权重 BigDecimal point = cpItemAmountCount.divide(totalAmount, 4, BigDecimal.ROUND_HALF_UP);//权重 //根据权重来计算单品的旧金抵扣金额 return oldAmountCount.multiply(point); } }else{ return new BigDecimal(0); } } /** * 获取整单中被拆票的单品的积分抵扣金额 * @param item 单品 * @param partSales 零售信息 * @return */ public static BigDecimal getPointDiscountAmountForCPItem(PartSales partSales){ if(null == partSales){ return new BigDecimal(0); } if(null == partSales.getItemList() || partSales.getItemList().size() == 0){ return new BigDecimal(0); } //计算所有单品的合计金额 BigDecimal countAmount = new BigDecimal(0); for(Item item : partSales.getItemList()){ if(item.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ continue; } countAmount = countAmount.add(item.getFactAmount()); } if(partSales.getSalesType() == AppConstants.SALES_TYPE_SALES){//如果是基本零售 //计算被拆票的Item实收合计,即是拆票之前单品的实售 BigDecimal cpItemAmountCount = new BigDecimal(0); for(Item ii : partSales.getItemList()){ if(ii.isChaiPiao()){ cpItemAmountCount = cpItemAmountCount.add(ii.getFactAmount()); } } //计算拆票之前单品实售在整单合计中的权重 BigDecimal point = cpItemAmountCount.divide(countAmount, 4, BigDecimal.ROUND_HALF_UP);//权重 //根据权重来计算单品的旧金抵扣金额 return partSales.getMemberAmount().multiply(point); }else{ return new BigDecimal(0); } } /** * 结算方式对象转换 * @param rpArray * @return * @throws POSException */ public static List<CashierModel> convertRetailPsToCashierModels(Retail_P[] rpArray) throws POSException{ List<CashierModel> cmList = new ArrayList<CashierModel>(); for(int i=0; i<rpArray.length; i++){ Retail_P rp = rpArray[i]; CashierModel cm = new CashierModel(); cm.setAmount(rp.getSum()); cm.setID(rp.getPayModeID()); cm.setRate(rp.getPoundage()); cm.setName(baseService.getNameByPayModeId(rp.getPayModeID())); cm.setCardNumber(rp.getBankcardno()); cmList.add(cm); } return cmList; } /** * 结算方式信息转换 * @param rmpArray * @return * @throws POSException */ public static List<CashierModel> convertRetailMPsToCashierModels(Retail_MPI[] rmpArray) throws POSException{ List<CashierModel> cmList = new ArrayList<CashierModel>(); for(int i=0; i<rmpArray.length; i++){ Retail_MPI rp = rmpArray[i]; CashierModel cm = new CashierModel(); cm.setAmount(rp.getSum()); cm.setID(rp.getPayModeID()); cm.setRate(rp.getPoundage()); cm.setName(baseService.getNameByPayModeId(rp.getPayModeID())); cm.setCardNumber(rp.getBankcardno()); cmList.add(cm); } return cmList; } /** * 结算方式信息转换,退换货专用,要将旧金贴换金额补充到现金中 * @param rmpArray * @param oldAmount * @return * @throws POSException */ public static List<CashierModel> convertRetailMPsToCashierModelsForReturned(Retail_MPI[] rmpArray, BigDecimal oldAmount) throws POSException{ List<CashierModel> cmList = new ArrayList<CashierModel>(); for(int i=0; i<rmpArray.length; i++){ Retail_MPI rp = rmpArray[i]; CashierModel cm = new CashierModel(); CashierModel cmodel = baseService.getCashierModelById(rp.getPayModeID()); //退货时,需要将旧金金额补充到结算方式(现金cmodel.getIsNoMakeup() == 0)中 if(cmodel.getIsNoMakeup() == 0){ cm.setAmount((rp.getSum().add(oldAmount)).multiply(new BigDecimal(-1))); }else{ cm.setAmount(rp.getSum().multiply(new BigDecimal(-1))); } // cm.setAmount(rp.getSum().multiply(new BigDecimal(-1))); cm.setID(rp.getPayModeID()); cm.setRate(rp.getPoundage()); cm.setName(baseService.getNameByPayModeId(rp.getPayModeID())); cm.setIsPrint(rp.getIsPrint()); cm.setCardNumber(rp.getBankcardno()); cmList.add(cm); } return cmList; } /** * 发票信息转换 * @param fpArray * @param partSales * @return */ public static List<RetailFP> convertRetail_FPToRetailFP(Retail_Fp[] fpArray){ List<RetailFP> fpList = new ArrayList<RetailFP>(); for(int i=0; i<fpArray.length; i++){ Retail_Fp rp = fpArray[i]; RetailFP fp = new RetailFP(); fp.setFPDM(rp.getFPDM()); fp.setFPH(rp.getFPH()); fp.setFPMSID(String.valueOf(rp.getFPMSID())); fp.setInvoiceAmount(ProjectUtil.formatAmount(null, rp.getInvoiceAmount())); fp.setItemCode(rp.getItemCode()); fp.setItemID(String.valueOf(rp.getItemID())); fp.setUsedDate(ProjectUtil.getDateString(rp.getUsedDate())); fpList.add(fp); } return fpList; } /** * 设置旧金数据明细 * @param retail 零售数据 * @param partSales 零售信息 * @return */ public static Retail setOldGoldData(Retail retail, PartSales partSales){ List<Item> itemList = partSales.getItemList(); if(null == itemList || itemList.size() == 0){ return retail; } //设置旧金 List<OldGold> oldGoldList = new ArrayList<OldGold>(); for(Item item : itemList){ //根据itemType来判断,0零售 1 旧金 2 服务费 if(!item.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ continue; } OldGold og = new OldGold(); og.setItemCode(item.getItemCode()); og.setDocNum(partSales.getDocNum());//单据编号,取零售界面的单据编号 og.setIdfCode(item.getDocNum());//旧金单据编号 og.setLoss(item.getZDPYZL().subtract(item.getZDPZL()).divide(item.getZDPYZL(), 4, BigDecimal.ROUND_HALF_UP)); og.setMtartCode(item.getMATNR()); og.setNeatness(new BigDecimal(0.00));//ID纯色 og.setPrice_G(new BigDecimal(0.00)); og.setRefine(new BigDecimal(0.00)); og.setService(new BigDecimal(0.00)); og.setSum(item.getFactAmount()); og.setSuppliser(1); og.setType("1"); og.setWeight(new BigDecimal(0.00)); og.setWeight_F(new BigDecimal(0.00)); og.setWeight_G(new BigDecimal(0.00)); og.setWeight_R(new BigDecimal(0.00)); oldGoldList.add(og); } if(oldGoldList.size() > 0){ retail.setIsReplace(1); } retail.setOldGoldList(oldGoldList.size()>0?oldGoldList:null); return retail; } /** * 设置断料数据明细 * @param retail 零售数据 * @param partSales 零售信息 * @return */ public static Retail setUnSaleDetail(Retail retail, PartSales partSales){ List<Item> itemList = partSales.getItemList(); if(null == itemList || itemList.size() == 0){ return retail; } List<UnSalePart> unSalePartList = new ArrayList<UnSalePart>(); for(Item item : itemList){ if(null != item.getUnSalePart()){ unSalePartList.add(item.getUnSalePart()); } } retail.setUnSalePartList(unSalePartList.size()>0?unSalePartList:null); return retail; } /** * 计算零售结算 整单结算金额分配 * @param itemDto 单品数据 * @return */ public static List<RetailP> calculateRetailPList(PartSales partSales){ List<CashierModel> cmList = partSales.getCashierModelList(); if(null == cmList || cmList.size() == 0){ return null; } // 将没有付钱的结算方式过滤掉 List<CashierModel> newCmList = new ArrayList<CashierModel>(); for(CashierModel cm : cmList){ if(partSales.getSalesType() == AppConstants.SALES_TYPE_SALES){ if(cm.getAmount().compareTo(new BigDecimal(0)) == 1){ newCmList.add(cm); } }else{ if(cm.getAmount().compareTo(new BigDecimal(0)) == 0){ continue; }else{ newCmList.add(cm); } } } List<RetailP> retailPList = new ArrayList<RetailP>(); for(int i=0; i<newCmList.size(); i++){ CashierModel cmodel = newCmList.get(i); BigDecimal cmAmount = cmodel.getAmount(); RetailP retailP = new RetailP(); retailP.setDocNum(partSales.getDocNum());//单据编号,去零售界面的单据编号 retailP.setPayModeID(cmodel.getID()); retailP.setPoundage(cmodel.getRate()); BigDecimal factCmAmount = calculateCashierModelFactSumByMakeUp(cmodel, i, getCashierModelAmountTotal(newCmList),newCmList, partSales.getCashBackAmount()); factCmAmount = factCmAmount.setScale(2, BigDecimal.ROUND_HALF_UP); retailP.setSum(factCmAmount); BigDecimal poundageRate = cmAmount.multiply(cmodel.getRate()); poundageRate = poundageRate.setScale(2, BigDecimal.ROUND_HALF_UP); retailP.setPoundageRate(poundageRate); retailP.setMakeup(cmAmount.subtract(factCmAmount)); retailP.setCardNo(cmodel.getCardNumber()); retailPList.add(retailP); } return retailPList; } /** * 零售结算 拆分到每个商品的结算金额 * @param itemDto 单品数据 * @param factAmountCount 实际销售总金额 * @return */ public static List<RetailMP> calculateRetailMPList(PartSales partSales){ List<Item> items = partSales.getItemList(); if(null == items || items.size() == 0){ return null; } List<CashierModel> cmList = partSales.getCashierModelList(); if(null == cmList || cmList.size() == 0){ return null; } // 将没有付钱的结算方式过滤掉 List<CashierModel> newCmList = new ArrayList<CashierModel>(); for(CashierModel cm : cmList){ if(partSales.getSalesType() == AppConstants.SALES_TYPE_SALES){ if(cm.getAmount().compareTo(new BigDecimal(0)) == 1){ newCmList.add(cm); } }else{ if(cm.getAmount().compareTo(new BigDecimal(0)) == 0){ continue; }else{ newCmList.add(cm); } } } List<RetailMP> retailMPList = new ArrayList<RetailMP>(); BigDecimal factAmountCount = partSales.getCountAmount();//整单金额合计 //如果是换货交易,被换购的单品不需要保存在retailMP中;//排除旧金,旧金不需要上传retailMP数据 List<Item> newList = new ArrayList<Item>(); for(Item ii : items){ if(partSales.getSalesType() == AppConstants.SALES_TYPE_EXECHANGE){ if(ii.getItemType().equals(AppConstants.ITEM_TYPE_RETURNED)){ continue; }else{ newList.add(ii); } }else{ if(ii.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ continue; }else{ newList.add(ii); } } } //循环单品,获取每个单品,每种结算方式的retailMP for(int j=0; j<newList.size(); j++){ Item item = newList.get(j); BigDecimal itemFactAmount = item.getFactAmount(); //实际支持的钱,减去了旧金抵扣作为itemFactAmount itemFactAmount = itemFactAmount.subtract(getOldAmountForItem(item, j, partSales)); //循环收款方式,所有收到的钱,分担每个单品 BigDecimal addCmAmount = new BigDecimal(0);//结算分配金额累计 for(int i=0; i<newCmList.size(); i++){ BigDecimal cmAmount = newCmList.get(i).getAmount(); //将结算方式中收的钱减去找补的钱 cmAmount = calculateCashierModelFactSumByMakeUp(newCmList.get(i), i, factAmountCount, newCmList, partSales.getCashBackAmount()); RetailMP retailMP = new RetailMP(); retailMP.setDocNum(partSales.getDocNum());//单据编号,去零售界面的单据编号 retailMP.setIsPrint(newCmList.get(i).getIsPrint()); retailMP.setItemCode(item.getItemCode()); retailMP.setItemID(item.getId()); retailMP.setPayModeID(newCmList.get(i).getID());//结算方式ID retailMP.setPoundage(newCmList.get(i).getRate());//手续费比例 if(factAmountCount.compareTo(new BigDecimal(0)) == 0){ retailMP.setSum(new BigDecimal(0)); }else{ BigDecimal sum = new BigDecimal(0); //最后一种支付方式:单品的实际销售金额减去1到N-种支付方式的金额合计 if(i == newCmList.size()-1){ sum = itemFactAmount.subtract(addCmAmount); }else{ //单品的实际销售金额*(这种支付方式的金额/总金额) sum = itemFactAmount.multiply(cmAmount).divide(factAmountCount, 4, BigDecimal.ROUND_HALF_UP); sum = sum.setScale(2, BigDecimal.ROUND_HALF_UP); addCmAmount = addCmAmount.add(sum); } if(sum.compareTo(new BigDecimal(0)) == 0){ sum = new BigDecimal(sum.intValue()); } //退货或者换货 if(partSales.getSalesType() == AppConstants.SALES_TYPE_RETURNED || partSales.getSalesType() == AppConstants.SALES_TYPE_EXECHANGE){ retailMP.setSum(sum.add(null == item.getOldGoldAmount()?new BigDecimal(0):item.getOldGoldAmount()));//补充旧金到结算方式 }else{ retailMP.setSum(sum);//结算金额 } } BigDecimal result = retailMP.getSum().multiply(newCmList.get(i).getRate()); result = result.setScale(2,BigDecimal.ROUND_HALF_EVEN); retailMP.setPoundageRate(result);//手续费 retailMP.setCardNo(newCmList.get(i).getCardNumber()); retailMPList.add(retailMP); } } return retailMPList; } /** * modify by yujie !! 重新计算找补想的分摊方式 * @param cmodel * @param cmodelAmount * @param cmAmountCount * @param list * @param cashBackAmount * @return */ public static BigDecimal calculateCashierModelFactSumByMakeUp(CashierModel cmodel,int cmIndex, BigDecimal cmAmountCount, List<CashierModel> list, BigDecimal cashBackAmount){ BigDecimal ret = new BigDecimal(0); //只有结算方式为找补项的才会进行分摊 if(cmodel.getIsNoMakeup() == 0){ BigDecimal makupAmount = new BigDecimal(0); //计算结算方式中为找补项的金额合计 for (CashierModel cashierModel : list) { if(cashierModel.getIsNoMakeup() == 0 ){ makupAmount = makupAmount.add(cashierModel.getAmount()); } } if(null == cashBackAmount){ cashBackAmount = new BigDecimal(0); } if(cashBackAmount.compareTo(new BigDecimal(0)) < 0 || cmodel.getAmount().compareTo(new BigDecimal(0)) == 0){ return ret; } BigDecimal point = new BigDecimal(1); //结算方式为找补项的收款金额 / 找补金额合计 = 比重 if(cmAmountCount.compareTo(BigDecimal.ZERO) == 1){ point = cmodel.getAmount().divide(makupAmount, 4, BigDecimal.ROUND_HALF_UP); } //最后一个找补的结算方式 if(cmIndex == list.size()-1){ BigDecimal retAmount = new BigDecimal(0); BigDecimal cashbackCmAdd = new BigDecimal(0); for(CashierModel cmm : list){ if(cmm.getID() == cmodel.getID()){ //retAmount = cmodel.getAmount().subcashBackAmount.subtract(cashbackCmAdd);错误的逻辑 retAmount = cmodel.getAmount().subtract(cashBackAmount.subtract(cashbackCmAdd));//update by tandong at 20140315 }else{ BigDecimal amount = cashBackAmount.multiply(cmm.getAmount()).divide(makupAmount, 2, BigDecimal.ROUND_HALF_UP); cashbackCmAdd = cashbackCmAdd.add(amount); } } ret = retAmount; }else{ ret = cmodel.getAmount().subtract(cashBackAmount.multiply(point)); } }else{ //如果为非找补项,则返回原来的收款金额 return cmodel.getAmount(); } return ret; } /** * 计算应售金额合计 * @param partSales * @return */ public static BigDecimal calculateSalesAmountTotal(PartSales partSales){ BigDecimal ret = new BigDecimal(0); if(null == partSales){ return ret; } List<Item> itemList = partSales.getItemList(); if(null == itemList || itemList.size() == 0){ return ret; } for(Item item : itemList){ if(item.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ //如果是旧金则加上负数 ret = ret.add(null == item.getSalesAmount()?new BigDecimal(0):ProjectUtil.formatString("-"+item.getSalesAmount())); }else{ ret = ret.add(null == item.getSalesAmount()?new BigDecimal(0):item.getSalesAmount()); } } return ret; } /** * 计算实售金额合计,不包含退货 * @param partSales * @return */ private static BigDecimal calculateFactAmountTotalNoReturned(PartSales partSales){ BigDecimal ret = new BigDecimal(0); if(null == partSales){ return ret; } List<Item> itemList = partSales.getItemList(); if(null == itemList || itemList.size() == 0){ return ret; } for(Item item : itemList){ if(item.getItemType().equals(AppConstants.ITEM_TYPE_RETURNED)){ continue; } ret = ret.add(null == item.getFactAmount()?new BigDecimal(0):item.getFactAmount()); } return ret; } /** * 计算实收总金额(不含旧金和被换购的旧品) * @param partSales * @return */ public static BigDecimal calculateFactAmountTotalNoOldGoldAndReturned(PartSales partSales){ BigDecimal ret = new BigDecimal(0); if(null == partSales){ return ret; } List<Item> itemList = partSales.getItemList(); if(null == itemList || itemList.size() == 0){ return ret; } for(Item item : itemList){ if(item.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD) || item.getItemType().equals(AppConstants.ITEM_TYPE_RETURNED)){ }else{ ret = ret.add(null == item.getFactAmount()?new BigDecimal(0):item.getFactAmount()); } } return ret; } /** * 计算开票金额 * @param partSales * @return */ public static BigDecimal calculateInvoceAmountTotal(PartSales partSales){ BigDecimal factAmountCount = partSales.getCountAmount(); List<CashierModel> cms = partSales.getCashierModelList(); if(null == cms){ return factAmountCount; } for(CashierModel cm : cms){ if(cm.getIsPrint() == 0){//不开票 factAmountCount = factAmountCount.subtract(null == cm.getAmount()?new BigDecimal(0):cm.getAmount()); } } return factAmountCount;// } /** * 计算会员折扣率 * @param partSales * @return * @throws POSException */ public static BigDecimal calculateMemberDiscount(PartSales partSales) throws POSException{ IBaseService baseService = new BaseServiceImpl(); CardRule cardRule = baseService.getCardRuleByCardType(partSales.getVipUser().getCardTypeNM()); BigDecimal disCount = cardRule.getDiscount();//折扣率 return disCount.compareTo(new BigDecimal(0)) == 1?disCount:new BigDecimal(1); } /** * 计算会员折扣合计金额 * @param partSales * @return * @throws POSException */ public static BigDecimal calculateDiscountAmountM(PartSales partSales) throws POSException{ BigDecimal ret = new BigDecimal(0); if(null == partSales || partSales.getItemList().size() == 0){ return ret; } if(!partSales.isVip()){ return ret; } List<Item> itemList = partSales.getItemList(); IBaseService baseService = new BaseServiceImpl(); CardRule cardRule = baseService.getCardRuleByCardType(partSales.getVipUser().getCardTypeNM()); BigDecimal disCount = cardRule.getDiscount();//折扣率 String matnr = cardRule.getMatnr();//物料号(包含) for(Item item : itemList){ //旧金和服务费不参与计算 if(item.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD) || item.getItemType().equals(AppConstants.ITEM_TYPE_SERVICEFEE)){ continue; } //单品的物料组号=会员卡对应卡类型所打折的物料组号 if(!item.getMatkl().startsWith(matnr)){ continue; } if(item.getMatkl().startsWith("1")){//素金折扣在工费上 BigDecimal disAmount = item.getZJGF().subtract(item.getZJGF().multiply(disCount)); ret = ret.add(disAmount); }else{ BigDecimal disAmount = item.getFactAmount().subtract(item.getFactAmount().multiply(disCount)); ret = ret.add(disAmount); } } return ret.compareTo(new BigDecimal(0)) == 1?ret:new BigDecimal(0); } /** * 计算优惠总金额 * @param partSales * @return */ public static BigDecimal calculateDiscountAmountTotal(PartSales partSales){ BigDecimal ret = new BigDecimal(0); if(null == partSales){ return ret; } List<Item> itemList = partSales.getItemList(); if(null == itemList || itemList.size() == 0){ return ret; } for(Item item : itemList){ ret = ret.add(null == item.getPretlAmount()?new BigDecimal(0):item.getPretlAmount()); } if(!(ret.compareTo(new BigDecimal(0)) == 1)){ ret = new BigDecimal(0); } if(partSales.isMlimit()){//优惠金额加上抹零金额 ret = ret.add(partSales.getDiscountToZero()); } if(partSales.isMratio()){//优惠金额加上授权折扣金额 ret = ret.add(partSales.getDiscountAmount()); } ret = ret.setScale(2, BigDecimal.ROUND_HALF_UP); return ret; } /** * 获取需要打印发票的数量 * @param partSales * @return */ public static int getNeedPrintNum(PartSales partSales){ int needPrintNum = 0; if(null == partSales || null == partSales.getItemList() || partSales.getItemList().size() == 0){ return needPrintNum; } if(partSales.getSalesType() == AppConstants.SALES_TYPE_EXECHANGE){ for(Item item : partSales.getItemList()){ if(item.getItemType().equals(AppConstants.ITEM_TYPE_RETURNED_NEW)){ needPrintNum++; } } }else{ for(Item item : partSales.getItemList()){ if(item.getItemType().equals(AppConstants.ITEM_TYPE_OLDGOLD)){ continue; } // if(item.getItemType().equals(AppConstants.ITEM_TYPE_SERVICEFEE)){ // continue; // } needPrintNum++; } } return needPrintNum; } /** * 获取结算方式结算金额合计 * @param cms * @return */ public static BigDecimal getCashierModelAmountTotal(List<CashierModel> cms){ BigDecimal totalAmount = new BigDecimal(0); if(null == cms || cms.size() == 0){ return totalAmount; } for(CashierModel cm : cms){ if(null == cm.getAmount() || cm.getAmount().compareTo(new BigDecimal(0)) == 0){ continue; } totalAmount = totalAmount.add(cm.getAmount()); } if(!(totalAmount.compareTo(new BigDecimal(0)) == 1)){ totalAmount = new BigDecimal(0); } return totalAmount; } }