Beispiel #1
0
        public void WHTransactionDo(ISession session)
        {
            SOHead saleOrder = SOHead.Retrieve(session, this._saleOrderID);

            if (saleOrder.OrderType == SaleOrderType.Exchange)
            {
                this._orderTypeCode = ORDER_TYPE_CODE_ED;
            }
            else
            {
                this._orderTypeCode = ORDER_TYPE_CODE_SD;
            }
            ERPUtil.CommitWHTrans(session, this);
        }
        void IWHTransHead.AfterTransaction(ISession session)
        {
            DbSession  dbSession = session.DbSession as DbSession;
            IDbCommand command   = null;
            //CRM接口需要的退货类型
            int returnType = 0;

            switch (this.OrderTypeCode)
            {
            case ORDER_TYPE_MBR_RTN: returnType = 0; break;       //会员退货

            case ORDER_TYPE_LOGISTICS_RTN: returnType = 1; break; //物流退货

            case ORDER_TYPE_INNER_RTN: returnType = 2; break;     //内部退货

            case ORDER_TYPE_EXCHANGE_RTN:                         //换货退货,不需要调用CRM存储过程,只更新换货订单状态
            {
                SOHead saleOrder = SOHead.Query(session, this.ExchangeOrder);
                if (saleOrder == null)
                {
                    return;
                }
                //saleOrder.UpdateStatus(session, 25).UpdateLineStatus(session, 30);
                command = dbSession.CreateStoredProcCommand("f_order_change_confirm", new object[] { 0, saleOrder.ID });
                dbSession.ExecuteNonQuery(command);
                int r = Cast.Int((command.Parameters[0] as IDataParameter).Value);
                if (r == 0 || r == -2)
                {
                    return;
                }
                else
                {
                    throw new Exception("更新换货订单状态时出错,f_order_change_confirm返回" + r.ToString());
                }
            };

            default: throw new Exception("无效的退货类型");
            }
            //判断是否全退
            bool isReturnAll = false;
            int  snLineCount = session.CreateEntityQuery <CRMSNLine>()
                               .Where(Exp.Eq("SNID", this.RefOrderID))
                               .Count();

            isReturnAll = snLineCount == this._lines.Count; //第一步,发货单明细与退货明细数量不相等,则一定不是全退
            StringBuilder snLineIds = new StringBuilder();

            for (int i = 0; i < this._lines.Count; i++)
            {
                if (this._lines[i].Quantity != this._lines[i].DeliverQuantity)
                {
                    isReturnAll = false;
                }
                if (i != 0)
                {
                    snLineIds.Append(",");
                }
                snLineIds.Append(this._lines[i].RefOrderLineID.ToString()).Append("-").Append(this._lines[i].Quantity.ToString());
            }
            //检查:物流退货、内部退货必须是全退
            if (!isReturnAll && (this.OrderTypeCode == ORDER_TYPE_LOGISTICS_RTN || this.OrderTypeCode == ORDER_TYPE_INNER_RTN))
            {
                throw new Exception("物流退货、内部退货必须是全退");
            }

            //调用CRM存储过程
            if (isReturnAll)
            {
                //全退: ORDERS.P_RETURN_SHIPPINGNOTICES
                //        v_shipping_id number, --CRM发货单ID
                //        v_vouch varchar2, --退货单号码
                //        v_comments VARCHAR2, --退货备注信息
                //        v_operator_id NUMBER, --退货人,ERP与CRM用户不同,现在没有对应起来
                //        v_return_order_type INTEGER, --退货类型: 0会员退货,1物流退货,2内部退货
                //        v_is_bad INTEGER, --是否恶意退货
                //        v_return OUT NUMBER --返回值
                command = dbSession.CreateStoredProcCommand("ORDERS.P_RETURN_SHIPPINGNOTICES", new object[] { this.RefOrderID, this.OrderNumber, 0, returnType, this.IsMalicious ? 1 : 0, 0 });
            }
            else
            {
                //部分退货,目前只支持针对部分发货明细全退
                //2008-11-03: 部分退货可以指定退货数量了
                //  : ORDERS.P_PARTLY_RETURN2
                //        v_shipping_id number, --CRM发货单ID
                //        v_lines VARCHAR2, --发货单明细,格式为 明细ID1,明细ID2,明细ID3...
                //        v_vouch varchar2, --退货单号码
                //        v_return OUT NUMBER --返回值
                command = dbSession.CreateStoredProcCommand("ORDERS.p_partly_return", new object[] { this.RefOrderID, snLineIds.ToString(), this.OrderNumber, 0 });
            }

            dbSession.ExecuteNonQuery(command);
            //存储过程中
            IDataParameter param  = command.Parameters[command.Parameters.Count - 1] as IDataParameter;
            int            result = Cast.Int(param.Value);

            if (result < 0)
            {
                throw new Exception("退货时发生异常,异常信息: " + result.ToString());
            }

            //退货完成后添加退货统计信息
            command = dbSession.CreateStoredProcCommand("p_rpt_fi_sale_return", new object[] { this.OrderNumber, 0, 0 });
            dbSession.ExecuteNonQuery(command);
            param  = command.Parameters[1] as IDataParameter;
            result = Cast.Int(param.Value);
            //退货后出现不正常现象,原因是因为礼品、套装等优惠的幅度太大,退货后礼品和解套的套装都按原价计算,因此可能出现会员退货之后还需要再支付一定金额
            //解决方法:检查会员当前帐户余额是否足够(不能出现负数),出现负数时(例如退货后帐户余额变成-127)提示仓库人员,并且回滚事务
            //              仓库人员通知客服和财务,客服与会员进行确认,财务在会员帐户上手工充值(充值127),再由仓库执行退货操作
            //              上面这些事情做完之后,退货后会员帐户余额变成0
            decimal returnAmt = Cast.Decimal((command.Parameters[2] as IDataParameter).Value);

            if (returnAmt < 0)
            {
                //如果退货金额小于0,查会员帐户余额是否出现小于0的情况
                command = dbSession.CreateSqlStringCommand(@"
Select m.deposit
From mbr_members m
Inner Join ord_headers o On o.buyer_id=m.Id
Where o.so_number=:sonum");
                dbSession.AddParameter(command, ":sonum", DbTypeInfo.AnsiString(16), this.OrginalOrderNumber);
                decimal accountAmt = Cast.Decimal(dbSession.ExecuteScalar(command));
                if (accountAmt < 0)
                {
                    throw new Exception("该退货单退货后导致会员帐户出现负数,请联系客服人员进行处理(退货金额为" + returnAmt.ToString("#0.#0") + ",退货后帐户余额为" + accountAmt.ToString("#0.#0") + ")");
                }
            }
            switch (result)
            {
            case -1001:
                throw new Exception("本月的库存期间没有正常开启,请联系系统维护人员");

            case -1002:
                command = dbSession.CreateSqlStringCommand("select * from fi_rpt_sale_return where rt_number='" + this.OrderNumber + "'");
                DataSet ds = dbSession.ExecuteDataSet(command);
                throw new Exception("退货统计数据错误,请联系系统维护人员" + "<br />" +
                                    "销售:" + Cast.Decimal(ds.Tables[0].Rows[0]["sale_amt"]).ToString() + ", " +
                                    "发送费:" + Cast.Decimal(ds.Tables[0].Rows[0]["transport_amt"]).ToString() + ", " +
                                    "包装费:" + Cast.Decimal(ds.Tables[0].Rows[0]["package_amt"]).ToString() + ", " +
                                    "礼券:" + Cast.Decimal(ds.Tables[0].Rows[0]["coupons_amt"]).ToString() + ", " +
                                    "折扣:" + Cast.Decimal(ds.Tables[0].Rows[0]["discount_amt"]).ToString() + ", " +
                                    "礼金:" + Cast.Decimal(ds.Tables[0].Rows[0]["emoney_amt"]).ToString() + ", " +
                                    "帐户:" + Cast.Decimal(ds.Tables[0].Rows[0]["account_receivable"]).ToString() + ", " +
                                    "POS机:" + Cast.Decimal(ds.Tables[0].Rows[0]["pos_receivable"]).ToString() + ", " +
                                    "物流应收:" + Cast.Decimal(ds.Tables[0].Rows[0]["logis_receivable"]).ToString());

            default: break;
            }
        }