//计算多余额应退 /// <summary> /// 计算多余额应退 /// </summary> /// <param name="soSysNo">订单编号</param> /// <param name="orderAmt">订单总额</param> /// <param name="giftcardPay">积分支付额</param> /// <returns>多余退款额</returns> private decimal GetReturnAmt(int soSysNo, decimal orderAmt, decimal giftcardPay) { var validIncome = ExternalDomainBroker.GetValidSOIncomeInfo(soSysNo, SOIncomeOrderType.SO); if (validIncome == null) { return(0.0M); } decimal incomeAmt = validIncome.OrderAmt.Value; if (giftcardPay > 0.0M) { return((incomeAmt > 0.0M) ? (incomeAmt - giftcardPay - orderAmt) : 0.0M); } return((incomeAmt > 0.0M) ? (incomeAmt - orderAmt) : 0.0M); }
public SOInfo CloneSO(SOInfo entity) { //获取原先的订单 SOInfo oriSO = GetSOBySOSysNo(entity.SysNo.Value); if (oriSO.Items.Exists(x => x.PriceType == SOProductPriceType.GoldAcc || x.PriceType == SOProductPriceType.GuanAiAcc || x.PriceType == SOProductPriceType.SdoAccPrice)) { BizExceptionHelper.Throw("SO_CloneSO_GuanAiAccCannotClone"); } //捆绑销售不能拆分 if (!CheckSaleRule(oriSO, entity)) { BizExceptionHelper.Throw("SO_CloneSO_ComboCanNotClone"); } oriSO.Items.Clear(); oriSO.Items = entity.Items; oriSO.SysNo = NewSOSysNo(); oriSO.BaseInfo.HoldStatus = SOHoldStatus.Unhold; oriSO.BaseInfo.HoldReason = string.Empty; oriSO.BaseInfo.HoldUser = 0; //验证 if (oriSO.Items.Exists(item => item.ProductType == SOProductType.SelfGift)) { BizExceptionHelper.Throw("SO_CloneSO_NeweggGiftCannotClone"); } //合约机订单 团购订单 依旧换新订单不能拆分 if (oriSO.BaseInfo.SOType == SOType.GroupBuy) { BizExceptionHelper.Throw("SO_CloneSO_ParticularCannotClone"); } //帐期不能拆分 if (oriSO.BaseInfo.PayTypeSysNo.Value == 4) { BizExceptionHelper.Throw("SO_CloneSO_ZhangQiCannotClone"); } //存在AO不能拆分 if (ExternalDomainBroker.GetValidSOIncomeInfo(entity.SysNo.Value, BizEntity.Invoice.SOIncomeOrderType.AO) != null) { BizExceptionHelper.Throw("SO_CloneSO_ExistsAOCannotCannotClone"); } ExternalDomainBroker.CreateOperationLog("Create SO", BizLogType.Sale_SO_Create, entity.BaseInfo.SysNo.Value, entity.CompanyCode); ProcessSO(new SOAction.SOCommandInfo { Command = SOAction.SOCommand.Create, SOInfo = oriSO }); string note = oriSO.SysNo.ToString() + "["; oriSO.Items.ForEach(item => { note += item.ProductSysNo.ToString(); }); note += "]"; SODA.UpdateSONote(oriSO.SysNo.Value, note); ExternalDomainBroker.CreateOperationLog("更新订单(拆单)", BizLogType.Sale_SO_Update, entity.BaseInfo.SysNo.Value, entity.CompanyCode); return(oriSO); }
public ECCentral.BizEntity.Invoice.SOIncomeInfo GetValidSOIncomeInfo(int orderSysNo) { return(ExternalDomainBroker.GetValidSOIncomeInfo(orderSysNo)); }
public void CustomsPass() { XElement orderConfig = AppSettingHelper.OrderBizConfig; int userSysno = int.Parse(orderConfig.Element(XName.Get("SellerPortalUserInfo")).Element(XName.Get("UserSysNo")).Value); // int.Parse(orderConfig.SellerPortalUserInfo.UserSysNo); SOInfo soInfo = CurrentSO; //1.检查SO信息 //ValidateSOInfo(soInfo); if (soInfo.BaseInfo.Status.HasValue && soInfo.BaseInfo.Status.Value != SOStatus.Reported) { string errorMsg = string.Format("SO单{0}的状态不是“已申报待通关”,不能执行出库操作!", soInfo.BaseInfo.SOID); BizExceptionHelper.Throw(errorMsg); } #region 修改订单状态,调整库存,创建代销转财务记录 TransactionOptions option = new TransactionOptions(); option.IsolationLevel = IsolationLevel.ReadUncommitted; option.Timeout = TransactionManager.DefaultTimeout; using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, option)) { soInfo.BaseInfo.Status = SOStatus.CustomsPass; //设置出库状态 SODA.UpdateSOStatusToCustomsPass(soInfo.SysNo.Value); List <BizEntity.Inventory.InventoryAdjustItemInfo> adjustItemList = new List <BizEntity.Inventory.InventoryAdjustItemInfo>(); foreach (SOItemInfo soItem in soInfo.Items) { switch (soItem.ProductType.Value) { case SOProductType.Product: case SOProductType.Gift: case SOProductType.Award: case SOProductType.SelfGift: case SOProductType.Accessory: adjustItemList.Add(new BizEntity.Inventory.InventoryAdjustItemInfo { AdjustQuantity = soItem.Quantity.Value, ProductSysNo = soItem.ProductSysNo.Value, StockSysNo = soItem.StockSysNo.Value }); break; case SOProductType.Coupon: case SOProductType.ExtendWarranty: break; } } //调整库存 ExternalDomainBroker.AdjustProductInventory(new BizEntity.Inventory.InventoryAdjustContractInfo { SourceActionName = BizEntity.Inventory.InventoryAdjustSourceAction.OutStock, SourceBizFunctionName = BizEntity.Inventory.InventoryAdjustSourceBizFunction.SO_Order, ReferenceSysNo = soInfo.SysNo.Value.ToString(), AdjustItemList = adjustItemList }); //Bowen:代码调整,加入事务中 2013-08-08 //模式2,3创建代销转财务日志 CreateConsigenToAccInfo(soInfo); #region 更新客户等级以及积分经验值 //增加客户经验值 //更新客户等级 //调整客户经验值(内部修改客户等级) int customerSysNo = soInfo.BaseInfo.CustomerSysNo.Value; decimal adjustValue = soInfo.BaseInfo.CashPay + soInfo.BaseInfo.PayPrice.Value + soInfo.BaseInfo.ShipPrice.Value + soInfo.BaseInfo.PremiumAmount.Value + soInfo.BaseInfo.PromotionAmount.Value; string logMemo = string.Format("SO#{0}:购物加经验值。", soInfo.SysNo); ExternalDomainBroker.AdjustCustomerExperience(customerSysNo, adjustValue, BizEntity.Customer.ExperienceLogType.MerchantSOOutbound, logMemo); //增加推荐用户的经验值 AddExperienceByRecommend(soInfo); //给款到发货用户加积分 AddPointForCustomer(soInfo); #endregion 更新客户等级以及积分经验值 #region 财务应收 //创建收款单 ECCentral.BizEntity.Invoice.SOIncomeInfo soIncomeInfo = ExternalDomainBroker.GetValidSOIncomeInfo(soInfo.SysNo.Value, BizEntity.Invoice.SOIncomeOrderType.SO); if (soIncomeInfo == null) { soIncomeInfo = new BizEntity.Invoice.SOIncomeInfo(); soIncomeInfo.OrderType = BizEntity.Invoice.SOIncomeOrderType.SO; soIncomeInfo.OrderSysNo = soInfo.SysNo; soIncomeInfo.OrderAmt = UtilityHelper.TruncMoney(soInfo.BaseInfo.SOTotalAmount); soIncomeInfo.IncomeAmt = UtilityHelper.TruncMoney(soInfo.BaseInfo.OriginalReceivableAmount); soIncomeInfo.PrepayAmt = Math.Max(soInfo.BaseInfo.PrepayAmount.Value, 0); soIncomeInfo.IncomeStyle = ECCentral.BizEntity.Invoice.SOIncomeOrderStyle.Normal; //soIncomeInfo.IncomeUserSysNo = soInfo.LastEditUserSysNumber ?? 0; //soIncomeInfo.IncomeTime = DateTime.Now; soIncomeInfo.Status = ECCentral.BizEntity.Invoice.SOIncomeStatus.Origin; soIncomeInfo.GiftCardPayAmt = soInfo.BaseInfo.GiftCardPay; soIncomeInfo.PointPay = soInfo.BaseInfo.PointPay; soIncomeInfo.PayAmount = soInfo.BaseInfo.OriginalReceivableAmount; if (soInfo.BaseInfo.SOSplitMaster.HasValue) { soIncomeInfo.MasterSoSysNo = soInfo.BaseInfo.SOSplitMaster; //获取母单号 } ExternalDomainBroker.CreateSOIncome(soIncomeInfo); } #endregion 财务应收 //this.PublishMessage(); scope.Complete(); } #endregion SOSendMessageProcessor messageProcessor = ObjectFactory <SOSendMessageProcessor> .Instance; //发送邮件 messageProcessor.SOOutStockSendEmailToCustomer(soInfo); //发送短信提醒 //发送短信 messageProcessor.SendSMS(soInfo, BizEntity.Customer.SMSType.OrderOutBound); if (soInfo.InvoiceInfo.IsVAT.Value && soInfo.InvoiceInfo.InvoiceType == ECCentral.BizEntity.Invoice.InvoiceType.SELF) { //增票提醒短信 messageProcessor.SendVATSMS(soInfo); //发送增值税发票SSB EventPublisher.Publish <ECCentral.Service.EventMessage.ImportVATSSBMessage>(new ECCentral.Service.EventMessage.ImportVATSSBMessage { SOSysNo = soInfo.SysNo.Value, StockSysNo = soInfo.Items[0].StockSysNo.Value, OrderType = EventMessage.ImportVATOrderType.SO }); } //调用OverseaInvoiceReceiptManagement.dbo.UP_InvoiceSync //插入Inovice_Master ObjectFactory <ECCentral.Service.IBizInteract.IInvoiceBizInteract> .Instance.SOOutStockInvoiceSync(soInfo.SysNo.Value, soInfo.Items[0].StockSysNo.Value, soInfo.InvoiceInfo.InvoiceNo, soInfo.CompanyCode); //EventPublisher.Publish<ECCentral.Service.EventMessage.CreateInvoiceSSBMessage>(new ECCentral.Service.EventMessage.CreateInvoiceSSBMessage //{ // CompanyCode = soInfo.CompanyCode, // InvoiceNo = soInfo.InvoiceInfo.InvoiceNo, // SOSysNo = soInfo.SysNo.Value, // StockSysNo = soInfo.Items[0].StockSysNo.Value //}); //记录日志 WriteLog(ECCentral.BizEntity.Common.BizLogType.Sale_SO_CustomsPass, "通关成功"); }
//改单 /// <summary> /// 改单 /// </summary> /// <param name="soSysNo">订单编号</param> public virtual void Update(int soSysNo) { var soProcessor = ObjectFactory <SOProcessor> .Instance; var soInfo = soProcessor.GetSOBySOSysNo(soSysNo); if (soInfo == null) { BizExceptionHelper.Throw("SO_SOIsNotExist"); } //是否货到付款 bool isPayWhenRecv = soProcessor.IsPayWhenReceived(soInfo.BaseInfo.PayTypeSysNo.Value); //查询订单出库记录 string outStock = m_da.GetOutStockString(soSysNo); //还没有出仓记录 if (string.IsNullOrEmpty(outStock)) { //直接作废 soProcessor.ProcessSO(new SOAction.SOCommandInfo { SOInfo = soInfo, Command = SOAction.SOCommand.Abandon }); return; } //获取出库收款信息 var invoiceMasterList = ExternalDomainBroker.GetSOInvoiceMaster(soSysNo); //计算总出库金额相关数据 //保价费 decimal premiumAmt = invoiceMasterList .Where(p => p.PremiumAmt.HasValue) .Sum(p => p.PremiumAmt.Value); //运费 decimal shippingCharge = invoiceMasterList .Where(p => p.ShippingCharge.HasValue) .Sum(p => p.ShippingCharge.Value); //附加费 decimal extraAmt = invoiceMasterList .Where(p => p.ExtraAmt.HasValue) .Sum(p => p.ExtraAmt.Value); //折扣金额 decimal discountAmt = invoiceMasterList .Where(p => p.DiscountAmt.HasValue) .Sum(p => p.DiscountAmt.Value); //优惠卷抵扣 decimal promotionAmt = invoiceMasterList .Where(p => p.PromotionAmt.HasValue) .Sum(p => p.PromotionAmt.Value); //获得积分? int pointAmt = invoiceMasterList .Where(p => p.GainPoint.HasValue) .Sum(p => p.GainPoint.Value); //出库发票额 decimal sumExtendPrice = invoiceMasterList .Where(p => p.InvoiceAmt.HasValue) .Sum(p => p.InvoiceAmt.Value); //礼品卡支付总额 decimal sumGiftCardPay = invoiceMasterList .Where(p => p.GiftCardPayAmt.HasValue) .Sum(p => p.GiftCardPayAmt.Value); //积分支付总额 decimal pointPay = invoiceMasterList .Where(p => p.PointPaid.HasValue) .Sum(p => p.PointPaid.Value); //计算多余额应退金额 decimal returnAmt = GetReturnAmt(soSysNo, sumExtendPrice, soInfo.BaseInfo.GiftCardPay.Value); //计算应退积分 int returnPoint = GetReturnPoint(soInfo, pointPay); //已预付款 decimal prePayAmount = invoiceMasterList .Where(p => p.PrepayAmt.HasValue) .Sum(p => p.PrepayAmt.Value); //预退款总额 decimal preReturnAmount = soInfo.BaseInfo.PrepayAmount.Value + prePayAmount; TransactionOptions options = new TransactionOptions(); options.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted; options.Timeout = TransactionManager.DefaultTimeout; using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, options)) { //删除未出库分仓的所有Item DeleteOrderItem4UpdatePending(soInfo.Items, soInfo.SysNo.Value, outStock); #region 更新so单据信息 //更新so单据信息 //删除后的SOInfo需要重新读取 //注意这里虽然事务没有提交,但是可以读取脏数据的方法获取 soInfo = soProcessor.GetSOBySOSysNo(soSysNo); soInfo.BaseInfo.PremiumAmount = premiumAmt; soInfo.BaseInfo.ShipPrice = shippingCharge; soInfo.BaseInfo.PayPrice = extraAmt; soInfo.BaseInfo.PointPay = 0; soInfo.BaseInfo.PromotionAmount = discountAmt; soInfo.BaseInfo.CouponAmount = promotionAmt; soInfo.BaseInfo.GainPoint = pointAmt; soInfo.BaseInfo.SOAmount = 0.0M; soInfo.Items.ForEach(x => { if (x.ProductType.HasValue && x.ProductType.Value != SOProductType.Coupon) { soInfo.BaseInfo.SOAmount += x.OriginalPrice * x.Quantity; } }); //现金支付为只读 //soInfo.BaseInfo.CashPay = soInfo.SOMaster.SOAmt + soInfo.SOMaster.PromotionValue + soMP.PointPay; soInfo.BaseInfo.PointPay = Convert.ToInt32(-1 * pointPay * ExternalDomainBroker.GetPointToMoneyRatio()); if (prePayAmount < 0.0M) { soInfo.BaseInfo.PrepayAmount = (-1) * prePayAmount; } soInfo.BaseInfo.GiftCardPay = (-1) * sumGiftCardPay; soProcessor.ProcessSO(new SOAction.SOCommandInfo { Command = SOAction.SOCommand.Update, SOInfo = soInfo }); #endregion 更新so单据信息 //更新改单状态 m_da.UpdateSOPendingStatus(soSysNo, SOPendingStatus.ChangeOrder); #warning 需要重构 重新计算是否并单 //重新计算是否并单 ObjectFactory <ISODA> .Instance.UpdateSOCombineInfo(soInfo.BaseInfo.SysNo.Value); //金额拆分 SOPriceSpliter priceSpliter = ObjectFactory <SOPriceSpliter> .Instance; priceSpliter.CurrentSO = soInfo; priceSpliter.SplitSO(); //重发消息 Resend_ShippingMessage(soSysNo); #region 调整积分 var pointAdjustReq = new ECCentral.BizEntity.Customer.AdjustPointRequest(); pointAdjustReq.CustomerSysNo = soInfo.BaseInfo.CustomerSysNo; pointAdjustReq.OperationType = ECCentral.BizEntity.Customer.AdjustPointOperationType.Abandon; pointAdjustReq.Point = returnPoint; pointAdjustReq.SOSysNo = soInfo.SysNo; pointAdjustReq.Source = "OrderMgmt"; pointAdjustReq.PointType = (int)ECCentral.BizEntity.Customer.AdjustPointType.UpdateSO; pointAdjustReq.Memo = ResourceHelper.Get("SO_Pending_ReturnPointMemo"); ExternalDomainBroker.AdjustPoint(pointAdjustReq); #endregion 调整积分 #region 退款(退余额) if (isPayWhenRecv) { //支持货到付款的改单 if (preReturnAmount > 0.0M) //(prepayAmt > sumExtendPrice) //预付款大于已出库总金额,要将多余的钱退回客户 { var customerPrepayReq = new CustomerPrepayLog(); customerPrepayReq.CustomerSysNo = soInfo.BaseInfo.CustomerSysNo; customerPrepayReq.SOSysNo = soInfo.SysNo; customerPrepayReq.AdjustAmount = preReturnAmount; customerPrepayReq.PrepayType = PrepayType.RemitReturn; customerPrepayReq.Note = ResourceHelper.Get("SO_Pending_PreReturnMemo", preReturnAmount); ExternalDomainBroker.AdjustPrePay(customerPrepayReq); } } else {//生成对应的多付款退款记录(invoiceservice)更新财务收款单中的OrderAmt金额(invoiceservice) if (returnAmt > 0) { //查询收款单 var incomeOrg = ExternalDomainBroker.GetValidSOIncomeInfo(soSysNo, SOIncomeOrderType.SO); if (incomeOrg == null) { BizExceptionHelper.Throw("SO_Income_Unknow", soSysNo.ToString()); } //修改原始的订单金额 incomeOrg.OrderAmt = incomeOrg.OrderAmt - returnAmt; ExternalDomainBroker.UpdateSOIncomeOrderAmount(incomeOrg.SysNo.Value, incomeOrg.OrderAmt.Value); //更新 //创建付款收支单 var income = new SOIncomeInfo { OrderSysNo = soInfo.SysNo , OrderAmt = -returnAmt , IncomeAmt = -returnAmt , OrderType = SOIncomeOrderType.OverPayment , Note = ResourceHelper.Get("SO_Pending_ReturnMemo") , Status = SOIncomeStatus.Origin , IncomeStyle = SOIncomeOrderStyle.Advanced , CompanyCode = soInfo.CompanyCode }; ExternalDomainBroker.CreateSOIncome(income); //创建银行收支单 SOIncomeRefundInfo refundInfo = new SOIncomeRefundInfo { SOSysNo = soInfo.SysNo , OrderSysNo = soInfo.SysNo , OrderType = RefundOrderType.OverPayment , RefundPayType = RefundPayType.PrepayRefund , RefundReason = 5 , Status = RefundStatus.Origin , Note = ResourceHelper.Get("SO_Pending_ReturnMemo") , RefundCashAmt = returnAmt , RefundPoint = 0 , ToleranceAmt = 0 , CompanyCode = soInfo.CompanyCode }; ExternalDomainBroker.CreateSOIncomeRefundInfo(refundInfo); } } #endregion 退款(退余额) #region 退礼品卡 //退礼品卡 if (sumGiftCardPay < 0.0M) { if (soInfo.SOGiftCardList != null) { List <GiftCard> reqList = new List <GiftCard>(); decimal needToPayAmt = sumGiftCardPay * (-1); for (int i = 0; i < soInfo.SOGiftCardList.Count; i++) { if (needToPayAmt <= 0) { soInfo.SOGiftCardList.RemoveAt(i); i--; continue; } soInfo.SOGiftCardList[i].AvailAmount = soInfo.SOGiftCardList[i].Amount.HasValue ? soInfo.SOGiftCardList[i].Amount.Value : 0; if (soInfo.SOGiftCardList[i].AvailAmount >= needToPayAmt) { soInfo.SOGiftCardList[i].Amount = needToPayAmt; soInfo.SOGiftCardList[i].AvailAmount -= needToPayAmt; needToPayAmt = 0; } else { soInfo.SOGiftCardList[i].Amount = soInfo.SOGiftCardList[i].AvailAmount; soInfo.SOGiftCardList[i].AvailAmount = 0; needToPayAmt -= soInfo.SOGiftCardList[i].Amount.Value; } reqList.Add(new GiftCard { Code = soInfo.SOGiftCardList[i].Code, ReferenceSOSysNo = soSysNo, CustomerSysNo = soInfo.SOGiftCardList[i].CustomerSysNo.Value, ConsumeAmount = soInfo.SOGiftCardList[i].Amount.Value }); } ExternalDomainBroker.GiftCardDeduction(reqList, soInfo.CompanyCode); } } #endregion 退礼品卡 scope.Complete(); } ExternalDomainBroker.WriteBizLog(ResourceHelper.Get("SO_Pending_UpdateLogFormat", soSysNo) , BizLogType.Sale_SO_Update , soSysNo , soInfo.CompanyCode); }