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;
}
}