コード例 #1
0
ファイル: AppCirculation.cs プロジェクト: renyh1013/dp2
        // 交违约金/撤销交违约金
        // parameters:
        //      strReaderBarcode    如果功能是"undo",可以将此参数设置为null。如果此参数不为null,则软件要进行核对,如果不是这个读者的已付违约金记录,则要报错
        //      strAmerceItemIdList id列表, 以逗号分割
        // 权限:需要有amerce/amercemodifyprice/amerceundo/amercemodifycomment等权限
        // 日志:
        //      要产生日志
        // return:
        //      result.Value    0 成功;1 部分成功(result.ErrorInfo中有信息)
        public LibraryServerResult Amerce(
            SessionInfo sessioninfo,
            string strFunction,
            string strReaderBarcode,
            AmerceItem[] amerce_items,
            out AmerceItem[] failed_items,
            out string strReaderXml)
        {
            strReaderXml = "";
            failed_items = null;

            LibraryServerResult result = new LibraryServerResult();

            if (String.Compare(strFunction, "amerce", true) == 0)
            {
                // 权限字符串
                if (StringUtil.IsInList("amerce", sessioninfo.RightsOrigin) == false)
                {
                    result.Value = -1;
                    result.ErrorInfo = "交违约金操作被拒绝。不具备 amerce 权限。";
                    result.ErrorCode = ErrorCode.AccessDenied;
                    return result;
                }
            }

            if (String.Compare(strFunction, "modifyprice", true) == 0)
            {
                // 权限字符串
                if (StringUtil.IsInList("amercemodifyprice", sessioninfo.RightsOrigin) == false)
                {
                    result.Value = -1;
                    result.ErrorInfo = "修改违约金额的操作被拒绝。不具备 amercemodifyprice 权限。";
                    result.ErrorCode = ErrorCode.AccessDenied;
                    return result;
                }
            }

            if (String.Compare(strFunction, "modifycomment", true) == 0)
            {
                /*
                // 权限字符串
                if (StringUtil.IsInList("amercemodifycomment", sessioninfo.RightsOrigin) == false)
                {
                    result.Value = -1;
                    result.ErrorInfo = "修改违约金之注释的操作被拒绝。不具备 amercemodifycomment 权限。";
                    result.ErrorCode = ErrorCode.AccessDenied;
                    return result;
                }
                 * */
            }

            if (String.Compare(strFunction, "undo", true) == 0)
            {
                // 权限字符串
                if (StringUtil.IsInList("amerceundo", sessioninfo.RightsOrigin) == false)
                {
                    result.Value = -1;
                    result.ErrorInfo = "撤销交违约金操作被拒绝。不具备 amerceundo 权限。";
                    result.ErrorCode = ErrorCode.AccessDenied;
                    return result;
                }
            }

            if (String.Compare(strFunction, "rollback", true) == 0)
            {
                // 权限字符串
                if (StringUtil.IsInList("amerce", sessioninfo.RightsOrigin) == false)
                {
                    result.Value = -1;
                    result.ErrorInfo = "撤回交违约金事务的操作被拒绝。不具备 amerce 权限。";
                    result.ErrorCode = ErrorCode.AccessDenied;
                    return result;
                }
            }

            if (strFunction != "rollback")
            {
                // 看看amerce_items中是否有价格变更或注释变更的情况
                bool bHasNewPrice = false;
                bool bHasOverwriteComment = false;    // NewComment具有、并且为覆盖。也就是说包括NewPrice和NewComment同时具有的情况
                for (int i = 0; i < amerce_items.Length; i++)
                {
                    AmerceItem item = amerce_items[i];

                    // NewPrice域中有值
                    if (String.IsNullOrEmpty(item.NewPrice) == false)
                    {
                        bHasNewPrice = true;
                    }

                    // NewComment域中有值
                    if (String.IsNullOrEmpty(item.NewComment) == false)
                    {
                        string strNewComment = item.NewComment;

                        bool bAppend = true;
                        if (string.IsNullOrEmpty(strNewComment) == false
                            && strNewComment[0] == '<')
                        {
                            bAppend = false;
                            strNewComment = strNewComment.Substring(1);
                        }
                        else if (string.IsNullOrEmpty(strNewComment) == false
                            && strNewComment[0] == '>')
                        {
                            bAppend = true;
                            strNewComment = strNewComment.Substring(1);
                        }

                        if (bAppend == false)
                            bHasOverwriteComment = true;
                    }
                }

                // 如果要变更价格,则需要额外的amercemodifyprice权限。
                // amercemodifyprice在功能amerce和modifyprice中都可能用到,关键是看是否提交了有新价格的参数
                if (bHasNewPrice == true)
                {
                    if (StringUtil.IsInList("amercemodifyprice", sessioninfo.RightsOrigin) == false)
                    {
                        result.Value = -1;
                        result.ErrorInfo = "含有价格变更要求的交违约金操作被拒绝。不具备 amercemodifyprice 权限。(仅仅具备 amerce 权限还不够的)";
                        result.ErrorCode = ErrorCode.AccessDenied;
                        return result;
                    }
                }

                if (bHasOverwriteComment == true)
                {
                    // 如果有了amerce权限,则暗含有了amerceappendcomment的权限

                    if (StringUtil.IsInList("amercemodifycomment", sessioninfo.RightsOrigin) == false)
                    {
                        result.Value = -1;
                        result.ErrorInfo = "含有违约金注释(覆盖型)变更要求的操作被拒绝。不具备 amercemodifycomment 权限。(仅仅具备 amerce 权限还不够的)";
                        result.ErrorCode = ErrorCode.AccessDenied;
                        return result;
                    }
                }
            }

            int nRet = 0;
            string strError = "";

            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);
            if (channel == null)
            {
                strError = "get channel error";
                goto ERROR1;
            }

            if (String.Compare(strFunction, "amerce", true) != 0
                && String.Compare(strFunction, "undo", true) != 0
                && String.Compare(strFunction, "modifyprice", true) != 0
                && String.Compare(strFunction, "modifycomment", true) != 0
                && String.Compare(strFunction, "rollback", true) != 0)
            {
                result.Value = -1;
                result.ErrorInfo = "未知的strFunction参数值 '" + strFunction + "'";
                result.ErrorCode = ErrorCode.InvalidParameter;
                return result;
            }

            // 如果是undo, 需要先检索出指定id的违约金库记录,然后从记录中得到<readerBarcode>,和参数核对
            if (String.Compare(strFunction, "undo", true) == 0)
            {
                // UNDO违约金交纳
                // return:
                //      -1  error
                //      0   succeed
                //      1   部分成功。strError中有报错信息
                nRet = UndoAmerces(
                    sessioninfo,
                    strReaderBarcode,
                    amerce_items,
                    out failed_items,
                    out strReaderXml,
                    out strError);
                if (nRet == -1)
                    goto ERROR1;

                // 2009/10/10 changed
                result.Value = nRet;
                if (nRet == 1)
                    result.ErrorInfo = strError;
                return result;
            }

            // 回滚
            // 2009/7/14
            if (String.Compare(strFunction, "rollback", true) == 0)
            {
                if (amerce_items != null)
                {
                    strError = "调用rollback功能时amerce_item参数必须为空";
                    goto ERROR1;
                }

                if (sessioninfo.AmerceIds == null
                    || sessioninfo.AmerceIds.Count == 0)
                {
                    strError = "当前没有可以rollback的违约金事项";
                    goto ERROR1;
                }

                // strReaderBarcode参数值一般为空即可。如果有值,则要求和SessionInfo对象中储存的最近一次的Amerce操作读者证条码号一致
                if (String.IsNullOrEmpty(strReaderBarcode) == false)
                {
                    if (sessioninfo.AmerceReaderBarcode != strReaderBarcode)
                    {
                        strError = "调用rollback功能时strReaderBarcode参数和最近一次Amerce操作的读者证条码号不一致";
                        goto ERROR1;
                    }
                }

                amerce_items = new AmerceItem[sessioninfo.AmerceIds.Count];

                for (int i = 0; i < sessioninfo.AmerceIds.Count; i++)
                {
                    AmerceItem item = new AmerceItem();
                    item.ID = sessioninfo.AmerceIds[i];

                    amerce_items[i] = item;
                }

                // UNDO违约金交纳
                // return:
                //      -1  error
                //      0   succeed
                //      1   部分成功。strError中有报错信息
                nRet = UndoAmerces(
                    sessioninfo,
                    sessioninfo.AmerceReaderBarcode,
                    amerce_items,
                    out failed_items,
                    out strReaderXml,
                    out strError);
                if (nRet == -1 || nRet == 1)
                    goto ERROR1;

                // 清空ids
                sessioninfo.AmerceIds = new List<string>();
                sessioninfo.AmerceReaderBarcode = "";

                result.Value = 0;
                return result;
            }

            // 加读者记录锁
#if DEBUG_LOCK_READER
            this.WriteErrorLog("Amerce 开始为读者加写锁 '" + strReaderBarcode + "'");
#endif
            this.ReaderLocks.LockForWrite(strReaderBarcode);

            try
            {
                // 读入读者记录
                strReaderXml = "";
                string strOutputReaderRecPath = "";
                byte[] reader_timestamp = null;
                nRet = this.GetReaderRecXml(
                    // sessioninfo.Channels,
                    channel,
                    strReaderBarcode,
                    out strReaderXml,
                    out strOutputReaderRecPath,
                    out reader_timestamp,
                    out strError);
                if (nRet == 0)
                {
                    result.Value = -1;
                    result.ErrorInfo = "读者证条码号 '" + strReaderBarcode + "' 不存在";
                    result.ErrorCode = ErrorCode.ReaderBarcodeNotFound;
                    return result;
                }
                if (nRet == -1)
                {
                    strError = "读入读者记录时发生错误: " + strError;
                    goto ERROR1;
                }

                // 所操作的读者库德馆代码
                string strLibraryCode = "";

                // 看看读者记录所从属的读者库的馆代码,是否被当前用户管辖
                if (String.IsNullOrEmpty(strOutputReaderRecPath) == false)
                {
                    // 获得读者库的馆代码
                    // return:
                    //      -1  出错
                    //      0   成功
                    nRet = GetLibraryCode(
            strOutputReaderRecPath,
            out strLibraryCode,
            out strError);
                    if (nRet == -1)
                        goto ERROR1;

                    // 检查当前操作者是否管辖这个读者库
                    // 观察一个读者记录路径,看看是不是在当前用户管辖的读者库范围内?
                    if (this.IsCurrentChangeableReaderPath(strOutputReaderRecPath,
            sessioninfo.LibraryCodeList) == false)
                    {
                        strError = "读者记录路径 '" + strOutputReaderRecPath + "' 从属的读者库不在当前用户管辖范围内";
                        goto ERROR1;
                    }
                }

                XmlDocument readerdom = null;
                nRet = LibraryApplication.LoadToDom(strReaderXml,
                    out readerdom,
                    out strError);
                if (nRet == -1)
                {
                    strError = "装载读者记录进入XML DOM时发生错误: " + strError;
                    goto ERROR1;
                }

                // 准备日志DOM
                XmlDocument domOperLog = new XmlDocument();
                domOperLog.LoadXml("<root />");
                DomUtil.SetElementText(domOperLog.DocumentElement,
    "libraryCode",
    strLibraryCode);    // 读者所在的馆代码
                DomUtil.SetElementText(domOperLog.DocumentElement,
                    "operation",
                    "amerce");

                // 具体动作
                DomUtil.SetElementText(domOperLog.DocumentElement,
                    "action", strFunction.ToLower());

                // 读者证条码号
                DomUtil.SetElementText(domOperLog.DocumentElement,
                    "readerBarcode", strReaderBarcode);

                //
                List<string> AmerceRecordXmls = null;
                List<string> CreatedNewPaths = null;

                List<string> Ids = null;


                string strOperTimeString = this.Clock.GetClock();   // RFC1123格式


                bool bReaderDomChanged = false; // 读者dom是否发生了变化,需要回存

                {
                    // 在日志中保留旧的读者记录
                    XmlNode node = DomUtil.SetElementText(domOperLog.DocumentElement,
        "oldReaderRecord", strReaderXml);
                    DomUtil.SetAttr(node, "recPath", strOutputReaderRecPath);
                }

                if (String.Compare(strFunction, "modifyprice", true) == 0)
                {
                    /*
                    // 在日志中保留旧的读者记录
                    XmlNode node = DomUtil.SetElementText(domOperLog.DocumentElement,
        "oldReaderRecord", strReaderXml);
                    DomUtil.SetAttr(node, "recPath", strOutputReaderRecPath);
                     * */

                    nRet = ModifyPrice(ref readerdom,
                        amerce_items,
                        out strError);
                    if (nRet == -1)
                        goto ERROR1;

                    if (nRet != 0)
                    {
                        bReaderDomChanged = true;
                        if (this.Statis != null)
                            this.Statis.IncreaseEntryValue(
                            strLibraryCode,
                            "违约金",
                            "修改次",
                            nRet);
                    }
                    else
                    {
                        // 如果一个事项也没有发生修改,则需要返回错误信息,以引起前端的警觉
                        strError = "警告:没有任何事项的价格(和注释)被修改。";
                        goto ERROR1;
                    }

                    goto SAVERECORD;
                }

                if (String.Compare(strFunction, "modifycomment", true) == 0)
                {
                    /*
                    // 在日志中保留旧的读者记录
                    XmlNode node = DomUtil.SetElementText(domOperLog.DocumentElement,
        "oldReaderRecord", strReaderXml);
                    DomUtil.SetAttr(node, "recPath", strOutputReaderRecPath);
                     * */

                    nRet = ModifyComment(
                        ref readerdom,
                        amerce_items,
                        out strError);
                    if (nRet == -1)
                        goto ERROR1;

                    if (nRet != 0)
                    {
                        bReaderDomChanged = true;
                        if (this.Statis != null)
                            this.Statis.IncreaseEntryValue(
                            strLibraryCode,
                            "违约金之注释",
                            "修改次",
                            nRet);
                    }
                    else
                    {
                        // 如果一个事项也没有发生修改,则需要返回错误信息,以引起前端的警觉
                        strError = "警告:没有任何事项的注释被修改。";
                        goto ERROR1;
                    }

                    goto SAVERECORD;
                }

                List<string> NotFoundIds = null;
                Ids = null;

                // 交违约金:在读者记录中去除所选的<overdue>元素,并且构造一批新记录准备加入违约金库
                // return:
                //      -1  error
                //      0   读者dom没有变化
                //      1   读者dom发生了变化
                nRet = DoAmerceReaderXml(
                    strLibraryCode,
                    ref readerdom,
                    amerce_items,
                    sessioninfo.UserID,
                    strOperTimeString,
                    out AmerceRecordXmls,
                    out NotFoundIds,
                    out Ids,
                    out strError);
                if (nRet == -1)
                    goto ERROR1;

                if (nRet == 1)
                    bReaderDomChanged = true;

                // 在违约金数据库中创建若干新的违约金记录
                // parameters:
                //      AmerceRecordXmls    需要写入的新记录的数组
                //      CreatedNewPaths 已经创建的新记录的路径数组。可以用于Undo(删除刚刚创建的新记录)
                nRet = CreateAmerceRecords(
                    // sessioninfo.Channels,
                    channel,
                    AmerceRecordXmls,
                    out CreatedNewPaths,
                    out strError);
                if (nRet == -1)
                {
                    // undo已经写入的部分记录
                    if (CreatedNewPaths != null
                        && CreatedNewPaths.Count != 0)
                    {
                        string strNewError = "";
                        nRet = DeleteAmerceRecords(
                            sessioninfo.Channels,
                            CreatedNewPaths,
                            out strNewError);
                        if (nRet == -1)
                        {
                            string strList = "";
                            for (int i = 0; i < CreatedNewPaths.Count; i++)
                            {
                                if (strList != "")
                                    strList += ",";
                                strList += CreatedNewPaths[i];
                            }
                            strError = "在创建新的违约金记录的过程中发生错误: " + strError + "。在Undo新创建的违约金记录的过程中,又发生错误: " + strNewError + ", 请系统管理员手工删除新创建的罚款记录: " + strList;
                            goto ERROR1;
                        }
                    }

                    goto ERROR1;
                }

            SAVERECORD:

                // 为写回读者、册记录做准备
                // byte[] timestamp = null;
                byte[] output_timestamp = null;
                string strOutputPath = "";

#if NO
                RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);
                if (channel == null)
                {
                    strError = "get channel error";
                    goto ERROR1;
                }
#endif
                long lRet = 0;

                if (bReaderDomChanged == true)
                {
                    strReaderXml = readerdom.OuterXml;

                    lRet = channel.DoSaveTextRes(strOutputReaderRecPath,
                        strReaderXml,
                        false,
                        "content,ignorechecktimestamp",
                        reader_timestamp,
                        out output_timestamp,
                        out strOutputPath,
                        out strError);
                    if (lRet == -1)
                        goto ERROR1;


                    // id list
                    /*
                    DomUtil.SetElementText(domOperLog.DocumentElement,
                        "idList", strAmerceItemIdList);
                     * */
                    WriteAmerceItemList(domOperLog, amerce_items);


                    /*
                    DomUtil.SetElementText(domOperLog.DocumentElement,
                        "readerBarcode", strReaderBarcode);
                    DomUtil.SetElementText(domOperLog.DocumentElement,
                        "itemBarcodeList", strItemBarcodeList);
                     */

                    // 仅当功能为amerce时,才把被修改的实体记录写入日志。
                    if (String.Compare(strFunction, "amerce", true) == 0)
                    {
                        Debug.Assert(AmerceRecordXmls.Count == CreatedNewPaths.Count, "");

                        // 写入多个重复的<amerceRecord>元素
                        for (int i = 0; i < AmerceRecordXmls.Count; i++)
                        {
                            XmlNode nodeAmerceRecord = domOperLog.CreateElement("amerceRecord");
                            domOperLog.DocumentElement.AppendChild(nodeAmerceRecord);
                            nodeAmerceRecord.InnerText = AmerceRecordXmls[i];

                            DomUtil.SetAttr(nodeAmerceRecord, "recPath", CreatedNewPaths[i]);
                            /*
                            DomUtil.SetElementText(domOperLog.DocumentElement,
                                "record", AmerceRecordXmls[i]);
                             **/

                            if (this.Statis != null)
                                this.Statis.IncreaseEntryValue(
                                strLibraryCode,
                                "违约金",
                                "给付次",
                                1);

                            {
                                string strPrice = "";
                                // 取出违约金记录中的金额数字
                                nRet = GetAmerceRecordPrice(AmerceRecordXmls[i],
                                    out strPrice,
                                    out strError);
                                if (nRet != -1)
                                {
                                    string strPrefix = "";
                                    string strPostfix = "";
                                    double fValue = 0.0;
                                    // 分析价格参数
                                    nRet = ParsePriceUnit(strPrice,
                                        out strPrefix,
                                        out fValue,
                                        out strPostfix,
                                        out strError);
                                    if (nRet != -1)
                                    {
                                        if (this.Statis != null)
                                            this.Statis.IncreaseEntryValue(
                                            strLibraryCode,
                                            "违约金",
                                            "给付元",
                                            fValue);
                                    }
                                    else
                                    {
                                        // 2012/11/15
                                        this.WriteErrorLog("累计 违约金 给付元 [" + strPrice + "] 时出错: " + strError);
                                    }
                                }
                            }
                        } // end of for
                    }

                    // 最新的读者记录
                    XmlNode node = DomUtil.SetElementText(domOperLog.DocumentElement,
        "readerRecord", strReaderXml);
                    DomUtil.SetAttr(node, "recPath", strOutputReaderRecPath);

                    string strOperTime = this.Clock.GetClock();
                    DomUtil.SetElementText(domOperLog.DocumentElement, "operator",
                        sessioninfo.UserID);   // 操作者
                    DomUtil.SetElementText(domOperLog.DocumentElement, "operTime",
                        strOperTime);   // 操作时间

                    nRet = this.OperLog.WriteOperLog(domOperLog,
                        sessioninfo.ClientAddress,
                        out strError);
                    if (nRet == -1)
                    {
                        strError = "Amerce() API 写入日志时发生错误: " + strError;
                        goto ERROR1;
                    }
                }

                // 记忆下最近一次Amerce操作的ID和读者证条码号
                if (strFunction != "rollback"
                    && Ids != null
                    && Ids.Count != 0)
                {
                    sessioninfo.AmerceReaderBarcode = strReaderBarcode;
                    sessioninfo.AmerceIds = Ids;
                }
            }
            finally
            {
                this.ReaderLocks.UnlockForWrite(strReaderBarcode);
#if DEBUG_LOCK_READER
                this.WriteErrorLog("Amerce 结束为读者加写锁 '" + strReaderBarcode + "'");
#endif
            }

            return result;
        ERROR1:
            result.Value = -1;
            result.ErrorInfo = strError;
            result.ErrorCode = ErrorCode.SystemError;
            return result;
        }
コード例 #2
0
ファイル: AppCirculation.cs プロジェクト: renyh1013/dp2
        // Undo一个已交费记录
        int UndoOneAmerce(SessionInfo sessioninfo,
            string strReaderBarcode,
            string strAmercedItemId,
            out string strReaderXml,
            out string strError)
        {
            strError = "";
            strReaderXml = "";

            RmsChannel channel = sessioninfo.Channels.GetChannel(this.WsUrl);
            if (channel == null)
            {
                strError = "get channel error";
                goto ERROR1;
            }

            long lRet = 0;
            int nRet = 0;

            string strFrom = "ID";
            string strQueryXml = "<target list='"
                + StringUtil.GetXmlStringSimple(this.AmerceDbName + ":" + strFrom)       // 2007/9/14
                + "'><item><word>"
                + strAmercedItemId + "</word><match>" + "exact" + "</match><relation>=</relation><dataType>string</dataType><maxCount>100</maxCount></item><lang>" + "zh" + "</lang></target>";

            lRet = channel.DoSearch(strQueryXml,
                "amerced",
                "", // strOuputStyle
                out strError);
            if (lRet == -1)
            {
                strError = "检索ID为 '" + strAmercedItemId + "' 的已付违约金记录出错: " + strError;
                return -1;
            }

            if (lRet == 0)
            {
                strError = "没有找到ID为 '" + strAmercedItemId + "' 的已付违约金记录";
                return -1;
            }

            List<string> aPath = null;
            lRet = channel.DoGetSearchResult("amerced",
                100,
                "zh",
                null,
                out aPath,
                out strError);
            if (lRet == -1)
            {
                strError = "检索ID为 '" + strAmercedItemId + "' 的已付违约金记录,获取浏览格式阶段出错: " + strError;
                return -1;
            }

            if (lRet == 0)
            {
                strError = "检索ID为 '" + strAmercedItemId + "' 的已付违约金记录,已检索命中,但是获取浏览格式没有找到";
                return -1;
            }

            if (aPath.Count == 0)
            {
                strError = "检索ID为 '" + strAmercedItemId + "' 的已付违约金记录,已检索命中,但是获取浏览格式没有找到";
                return -1;
            }

            if (aPath.Count > 1)
            {
                strError = "ID为 '" + strAmercedItemId + "' 的已付违约金记录检索出多条。请系统管理员及时更正此错误。";
                return -1;
            }

            string strAmercedRecPath = aPath[0];

            string strMetaData = "";
            byte[] amerced_timestamp = null;
            string strOutputPath = "";
            string strAmercedXml = "";

            lRet = channel.GetRes(strAmercedRecPath,
                out strAmercedXml,
                out strMetaData,
                out amerced_timestamp,
                out strOutputPath,
                out strError);
            if (lRet == -1)
            {
                strError = "获取已付违约金记录 '" + strAmercedRecPath + "' 时出错: " + strError;
                return -1;
            }

            string strOverdueString = "";
            string strOutputReaderBarcode = "";

            // 将违约金记录格式转换为读者记录中的<overdue>元素格式
            // return:
            //      -1  error
            //      0   strAmercedXml中<state>元素的值为*非*"settlemented"
            //      1   strAmercedXml中<state>元素的值为"settlemented"
            nRet = ConvertAmerceRecordToOverdueString(strAmercedXml,
                out strOutputReaderBarcode,
                out strOverdueString,
                out strError);
            if (nRet == -1)
                return -1;
            if (nRet == 1)
            {
                strError = "ID为 " + strAmercedItemId + " (路径为 '" + strOutputPath + "' ) 的违约金库记录其状态为 已结算(settlemented),不能撤回交费操作";
                return -1;
            }

            // 如果strReaderBarcode参数值非空,则要检查一下检索出来的已付违约金记录是否真的属于这个读者
            if (String.IsNullOrEmpty(strReaderBarcode) == false
                && strReaderBarcode != strOutputReaderBarcode)
            {
                strError = "ID为 '" + strAmercedItemId + "' 的已付违约金记录,并不是属于所指定的读者 '" + strReaderBarcode + "',而是属于另一读者 '" + strOutputReaderBarcode + "'";
                return -1;
            }

            // 加读者记录锁
#if DEBUG_LOCK_READER
            this.WriteErrorLog("UndoOneAmerce 开始为读者加写锁 '" + strReaderBarcode + "'");
#endif
            this.ReaderLocks.LockForWrite(strReaderBarcode);

            try
            {
                // 读入读者记录
                strReaderXml = "";
                string strOutputReaderRecPath = "";
                byte[] reader_timestamp = null;

                nRet = this.GetReaderRecXml(
                    // sessioninfo.Channels,
                    channel,
                    strReaderBarcode,
                    out strReaderXml,
                    out strOutputReaderRecPath,
                    out reader_timestamp,
                    out strError);
                if (nRet == 0)
                {
                    strError = "读者证条码号 '" + strReaderBarcode + "' 不存在";
                    goto ERROR1;
                }
                if (nRet == -1)
                {
                    strError = "读入读者记录时发生错误: " + strError;
                    goto ERROR1;
                }

                string strLibraryCode = "";
                // 看看读者记录所从属的读者库的馆代码,是否被当前用户管辖
                if (String.IsNullOrEmpty(strOutputReaderRecPath) == false)
                {
                    // 检查当前操作者是否管辖这个读者库
                    // 观察一个读者记录路径,看看是不是在当前用户管辖的读者库范围内?
                    if (this.IsCurrentChangeableReaderPath(strOutputReaderRecPath,
            sessioninfo.LibraryCodeList,
            out strLibraryCode) == false)
                    {
                        strError = "读者记录路径 '" + strOutputReaderRecPath + "' 从属的读者库不在当前用户管辖范围内";
                        goto ERROR1;
                    }
                }

                XmlDocument readerdom = null;
                nRet = LibraryApplication.LoadToDom(strReaderXml,
                    out readerdom,
                    out strError);
                if (nRet == -1)
                {
                    strError = "装载读者记录进入XML DOM时发生错误: " + strError;
                    goto ERROR1;
                }

                // 准备日志DOM
                XmlDocument domOperLog = new XmlDocument();
                domOperLog.LoadXml("<root />");
                DomUtil.SetElementText(domOperLog.DocumentElement,
                    "libraryCode",
                    strLibraryCode);    // 读者所在的馆代码
                DomUtil.SetElementText(domOperLog.DocumentElement, "operation",
                    "amerce");

                bool bReaderDomChanged = false;

                // 修改读者记录
                // 增添超期信息
                if (String.IsNullOrEmpty(strOverdueString) != true)
                {
                    XmlDocumentFragment fragment = readerdom.CreateDocumentFragment();
                    fragment.InnerXml = strOverdueString;

                    // 看看根下面是否有overdues元素
                    XmlNode root = readerdom.DocumentElement.SelectSingleNode("overdues");
                    if (root == null)
                    {
                        root = readerdom.CreateElement("overdues");
                        readerdom.DocumentElement.AppendChild(root);
                    }

                    // 2008/11/11
                    // undo交押金
                    XmlNode node_added = root.AppendChild(fragment);
                    bReaderDomChanged = true;

                    Debug.Assert(node_added != null, "");
                    string strReason = DomUtil.GetAttr(node_added, "reason");
                    if (strReason == "押金。")
                    {
                        string strPrice = "";

                        strPrice = DomUtil.GetAttr(node_added, "newPrice");
                        if (String.IsNullOrEmpty(strPrice) == true)
                            strPrice = DomUtil.GetAttr(node_added, "price");
                        else
                        {
                            Debug.Assert(strPrice.IndexOf('%') == -1, "从newPrice属性中取出来的价格字符串,岂能包含%符号");
                        }

                        if (String.IsNullOrEmpty(strPrice) == false)
                        {
                            // 需要从<foregift>元素中减去这个价格
                            string strContent = DomUtil.GetElementText(readerdom.DocumentElement,
                                "foregift");

                            string strNegativePrice = "";
                            // 将形如"-123.4+10.55-20.3"的价格字符串反转正负号
                            // parameters:
                            //      bSum    是否要顺便汇总? true表示要汇总
                            nRet = PriceUtil.NegativePrices(strPrice,
                                false,
                                out strNegativePrice,
                                out strError);
                            if (nRet == -1)
                            {
                                strError = "反转价格字符串 '" + strPrice + "时发生错误: " + strError;
                                goto ERROR1;
                            }

                            strContent = PriceUtil.JoinPriceString(strContent, strNegativePrice);

                            DomUtil.SetElementText(readerdom.DocumentElement,
                                "foregift",
                                strContent);
                            bReaderDomChanged = true;
                        }
                    }
                }

                if (bReaderDomChanged == true)
                {
                    byte[] output_timestamp = null;

                    strReaderXml = readerdom.OuterXml;
                    // 野蛮写入
                    lRet = channel.DoSaveTextRes(strOutputReaderRecPath,
                        strReaderXml,
                        false,
                        "content,ignorechecktimestamp", // ?????
                        reader_timestamp,
                        out output_timestamp,
                        out strOutputPath,
                        out strError);
                    if (lRet == -1)
                        goto ERROR1;

                    int nRedoDeleteCount = 0;
                REDO_DELETE:
                    // 删除已付违约金记录
                    lRet = channel.DoDeleteRes(strAmercedRecPath,
                        amerced_timestamp,
                        out output_timestamp,
                        out strError);
                    if (lRet == -1)
                    {
                        if (channel.ErrorCode == ChannelErrorCode.TimestampMismatch
                            && nRedoDeleteCount < 10)
                        {
                            nRedoDeleteCount++;
                            amerced_timestamp = output_timestamp;
                            goto REDO_DELETE;
                        }
                        strError = "删除已付违约金记录 '" + strAmercedRecPath + "' 失败: " + strError;
                        this.WriteErrorLog(strError);
                        goto ERROR1;
                    }

                    // 具体动作
                    DomUtil.SetElementText(domOperLog.DocumentElement,
                        "action", "undo");

                    // id list
                    /*
                    DomUtil.SetElementText(domOperLog.DocumentElement,
                        "idList", strAmercedItemId);
                     * */
                    AmerceItem[] amerce_items = new AmerceItem[1];
                    amerce_items[0] = new AmerceItem();
                    amerce_items[0].ID = strAmercedItemId;
                    WriteAmerceItemList(domOperLog,
                        amerce_items);


                    DomUtil.SetElementText(domOperLog.DocumentElement,
                        "readerBarcode", strReaderBarcode);

                    /*
                    DomUtil.SetElementText(domOperLog.DocumentElement,
                        "amerceItemID", strAmercedItemId);
                     */

                    // 删除掉的违约金记录
                    XmlNode node = DomUtil.SetElementText(domOperLog.DocumentElement,
                        "amerceRecord", strAmercedXml);
                    DomUtil.SetAttr(node, "recPath", strAmercedRecPath);

                    // 最新的读者记录
                    node = DomUtil.SetElementText(domOperLog.DocumentElement,
                        "readerRecord", strReaderXml);
                    DomUtil.SetAttr(node, "recPath", strOutputReaderRecPath);


                    string strOperTime = this.Clock.GetClock();
                    DomUtil.SetElementText(domOperLog.DocumentElement, "operator",
                        sessioninfo.UserID);   // 操作者
                    DomUtil.SetElementText(domOperLog.DocumentElement, "operTime",
                        strOperTime);   // 操作时间

                    nRet = this.OperLog.WriteOperLog(domOperLog,
                        sessioninfo.ClientAddress,
                        out strError);
                    if (nRet == -1)
                    {
                        strError = "Amerce() API 写入日志时发生错误: " + strError;
                        goto ERROR1;
                    }

                    if (this.Statis != null)
                        this.Statis.IncreaseEntryValue(strLibraryCode,
                        "违约金",
                        "取消次",
                        1);

                    {
                        string strPrice = "";
                        // 取出违约金记录中的金额数字
                        nRet = GetAmerceRecordPrice(strAmercedXml,
                            out strPrice,
                            out strError);
                        if (nRet != -1)
                        {
                            string strPrefix = "";
                            string strPostfix = "";
                            double fValue = 0.0;
                            // 分析价格参数
                            nRet = ParsePriceUnit(strPrice,
                                out strPrefix,
                                out fValue,
                                out strPostfix,
                                out strError);
                            if (nRet != -1)
                            {
                                if (this.Statis != null)
                                    this.Statis.IncreaseEntryValue(
                                    strLibraryCode,
                                    "违约金",
                                    "取消元",
                                    fValue);
                            }
                        }
                    }
                }
            }
            finally
            {
                this.ReaderLocks.UnlockForWrite(strReaderBarcode);
#if DEBUG_LOCK_READER
                this.WriteErrorLog("UndoOneAmerce 结束为读者加写锁 '" + strReaderBarcode + "'");
#endif

            }

            return 0;
        ERROR1:
            return -1;
        }
コード例 #3
0
ファイル: AppCirculation.cs プロジェクト: renyh1013/dp2
        // UNDO违约金交纳
        // return:
        //      -1  error
        //      0   succeed
        //      1   部分成功。strError中有报错信息,failed_item中有那些没有被处理的item的列表
        int UndoAmerces(
            SessionInfo sessioninfo,
            string strReaderBarcode,
            AmerceItem[] amerce_items,
            out AmerceItem[] failed_items,
            out string strReaderXml,
            out string strError)
        {
            strError = "";
            strReaderXml = "";
            failed_items = null;
            int nErrorCount = 0;

            List<string> OverdueStrings = new List<string>();
            List<string> AmercedRecPaths = new List<string>();

            // string[] ids = strAmercedItemIdList.Split(new char[] { ',' });
            List<AmerceItem> failed_list = new List<AmerceItem>();
            for (int i = 0; i < amerce_items.Length; i++)
            {
                AmerceItem item = amerce_items[i];

                /*
                string strID = ids[i].Trim();
                 * */
                if (String.IsNullOrEmpty(item.ID) == true)
                    continue;

                string strTempError = "";

                int nRet = UndoOneAmerce(sessioninfo,
                    strReaderBarcode,
                    item.ID,
                    out strReaderXml,
                    out strTempError);
                if (nRet == -1)
                {
                    if (String.IsNullOrEmpty(strError) == false)
                        strError += ";\r\n";
                    strError += strTempError;
                    nErrorCount++;
                    // return -1;
                    failed_list.Add(item);
                }
            }

            // 每个ID都发生了错误
            if (nErrorCount >= amerce_items.Length)
                return -1;

            // 部分发生错误
            if (nErrorCount > 0)
            {
                failed_items = new AmerceItem[failed_list.Count];
                failed_list.CopyTo(failed_items);

                strError = "操作部分成功。(共提交了 " + amerce_items.Length + " 个事项,发生错误的有 " + nErrorCount + " 个) \r\n" + strError;
                return 1;
            }

            return 0;
        }
コード例 #4
0
ファイル: AppCirculation.cs プロジェクト: renyh1013/dp2
        // 交违约金:在读者记录中去除所选的<overdue>元素,并且构造一批新记录准备加入违约金库
        // parameters:
        //      strLibraryCode  读者记录从属的馆代码
        // return:
        //      -1  error
        //      0   读者dom没有变化
        //      1   读者dom发生了变化
        static int DoAmerceReaderXml(
            string strLibraryCode,
            ref XmlDocument readerdom,
            AmerceItem[] amerce_items,
            string strOperator,
            string strOperTimeString,
            out List<string> AmerceRecordXmls,
            out List<string> NotFoundIds,
            out List<string> Ids,
            out string strError)
        {
            strError = "";
            AmerceRecordXmls = new List<string>();
            NotFoundIds = new List<string>();
            Ids = new List<string>();
            int nRet = 0;

            string strReaderBarcode = DomUtil.GetElementText(readerdom.DocumentElement,
                "barcode");
            if (String.IsNullOrEmpty(strReaderBarcode) == true)
            {
                strError = "读者记录中竟然没有<barcode>元素值";
                return -1;
            }

            bool bChanged = false;  // 读者dom是否发生了改变

            // string strNotFoundIds = "";

            for (int i = 0; i < amerce_items.Length; i++)
            {
                AmerceItem item = amerce_items[i];

                // string strID = ids[i].Trim();
                if (String.IsNullOrEmpty(item.ID) == true)
                    continue;

                XmlNode node = readerdom.DocumentElement.SelectSingleNode("overdues/overdue[@id='" + item.ID + "']");
                if (node == null)
                {
                    NotFoundIds.Add(item.ID);

                    /*
                    if (strNotFoundIds != "")
                        strNotFoundIds += ",";
                    strNotFoundIds += item.ID;
                     * */
                    continue;
                }

                string strForegiftPrice = DomUtil.GetElementText(readerdom.DocumentElement,
                    "foregift");

                string strFinalPrice = "";  // 最终使用的价格字符串。这是从item.NewPrice和node节点的price属性中选择出来,并且经过去除宏操作的一个最后价格字符串
                string strAmerceRecord = "";
                // 将读者记录中的<overdue>元素和属性转换为违约金库的记录格式
                nRet = ConvertOverdueStringToAmerceRecord(node,
                    strLibraryCode,
                    strReaderBarcode,
                    "amerced",
                    item.NewPrice,
                    item.NewComment,
                    strOperator,
                    strOperTimeString,
                    strForegiftPrice,
                    out strFinalPrice,
                    out strAmerceRecord,
                    out strError);
                if (nRet == -1)
                    return -1;

                AmerceRecordXmls.Add(strAmerceRecord);

                Ids.Add(item.ID);

                // 如果是押金,需要增/减<foregift>元素内的价格值。交费为增,退费为减。不过正负号已经含在价格字符串中,可以都理解为交费
                string strReason = "";
                strReason = DomUtil.GetAttr(node, "reason");

                // 2008/11/11
                if (strReason == "押金。")
                {
                    string strNewPrice = "";

                    /*
                    string strOldPrice = DomUtil.GetElementText(readerdom.DocumentElement,
                        "foregift");

                    if (strOldPrice.IndexOf('%') != -1)
                    {
                        strError = "来自读者记录<foregift>元素的价格字符串 '" + strOldPrice + "' 格式错误:价格字符串中不允许出现%符号";
                        return -1;
                    }

                    string strPrice = "";

                    if (String.IsNullOrEmpty(item.NewPrice) == true)
                        strPrice = DomUtil.GetAttr(node, "price");
                    else
                        strPrice = item.NewPrice;

                    // 看看价格字符串是否为宏?
                    if (strPrice == "%return_foregift_price%")
                    {
                        // 将形如"-123.4+10.55-20.3"的价格字符串反转正负号
                        // parameters:
                        //      bSum    是否要顺便汇总? true表示要汇总
                        nRet = PriceUtil.NegativePrices(strOldPrice,
                            true,
                            out strPrice,
                            out strError);
                        if (nRet == -1)
                        {
                            strError = "反转(来自读者记录中的<foregift>元素的)价格字符串 '" + strOldPrice + "' 时出错: " + strError;
                            return -1;
                        }
                    }

                    if (strPrice.IndexOf('%') != -1)
                    {
                        strError = "价格字符串 '" + strPrice + "' 格式错误:除了使用宏%return_foregift_price%以外,价格字符串中不允许出现%符号";
                        return -1;
                    }

                    if (String.IsNullOrEmpty(strOldPrice) == false)
                    {
                        strNewPrice = PriceUtil.JoinPriceString(strOldPrice, strPrice);
                    }
                    else
                    {
                        strNewPrice = strPrice;
                    }
                     * */
                    if (String.IsNullOrEmpty(strForegiftPrice) == false)
                    {
                        strNewPrice = PriceUtil.JoinPriceString(strForegiftPrice, strFinalPrice);
                    }
                    else
                    {
                        strNewPrice = strFinalPrice;
                    }


                    DomUtil.SetElementText(readerdom.DocumentElement,
                        "foregift",
                        strNewPrice);

                    // 是否顺便写入最近一次的交费时间?
                    bChanged = true;
                }

                // 在读者记录中删除这个节点
                node.ParentNode.RemoveChild(node);
                bChanged = true;
            }

            /*
            if (strNotFoundIds != "")
            {
                strError = "下列id没有相匹配的<overdue>元素" + strNotFoundIds;
                return -1;
            }*/
            if (NotFoundIds.Count > 0)
            {
                strError = "下列id没有相匹配的<overdue>元素: " + StringUtil.MakePathList(NotFoundIds);
                return -1;
            }


            if (bChanged == true)
                return 1;
            return 0;
        }
コード例 #5
0
ファイル: AppCirculation.cs プロジェクト: renyh1013/dp2
        // 在日志DOM中写入违约金事项信息
        static void WriteAmerceItemList(XmlDocument domOperLog,
            AmerceItem[] amerce_items)
        {
            XmlNode root = domOperLog.CreateElement("amerceItems");
            domOperLog.DocumentElement.AppendChild(root);

            for (int i = 0; i < amerce_items.Length; i++)
            {
                AmerceItem item = amerce_items[i];

                XmlNode node = domOperLog.CreateElement("amerceItem");
                root.AppendChild(node);

                DomUtil.SetAttr(node, "id", item.ID);

                if (String.IsNullOrEmpty(item.NewPrice) == false)
                    DomUtil.SetAttr(node, "newPrice", item.NewPrice);

                // 2007/4/17
                if (String.IsNullOrEmpty(item.NewComment) == false)
                    DomUtil.SetAttr(node, "newComment", item.NewComment);

            }

            /*

            // id list
            DomUtil.SetElementText(domOperLog.DocumentElement,
                "idList", strAmerceItemIdList);
            */
        }
コード例 #6
0
ファイル: AppCirculation.cs プロジェクト: renyh1013/dp2
        // 从日志DOM中读出违约金事项信息
        public static AmerceItem[] ReadAmerceItemList(XmlDocument domOperLog)
        {
            XmlNodeList nodes = domOperLog.DocumentElement.SelectNodes("amerceItems/amerceItem");
            AmerceItem[] results = new AmerceItem[nodes.Count];

            for (int i = 0; i < nodes.Count; i++)
            {
                XmlNode node = nodes[i];

                string strID = DomUtil.GetAttr(node, "id");
                string strNewPrice = DomUtil.GetAttr(node, "newPrice");
                string strComment = DomUtil.GetAttr(node, "newComment");

                results[i] = new AmerceItem();
                results[i].ID = strID;
                results[i].NewPrice = strNewPrice;
                results[i].NewComment = strComment;    // 2007/4/17
            }

            return results;
        }
コード例 #7
0
ファイル: AppCirculation.cs プロジェクト: renyh1013/dp2
        // 2008/6/19
        // 根据AmerceItem数组,修改readerdom中的<amerce>元素中的comment属性。
        // 为功能"modifycomment"服务。
        int ModifyComment(
            ref XmlDocument readerdom,
            AmerceItem[] amerce_items,
            out string strError)
        {
            strError = "";
            int nChangedCount = 0;

            for (int i = 0; i < amerce_items.Length; i++)
            {
                AmerceItem item = amerce_items[i];

                // 不能同时修改价格。
                if (String.IsNullOrEmpty(item.NewPrice) == false)
                {
                    strError = "不能用modifycomment子功能来修改价格,请改用modifyprice子功能";
                    return -1;
                }

                /*
                // 遇到NewComment域值为空、并且为追加的,直接跳过
                if (String.IsNullOrEmpty(item.NewComment) == true
                    && strFunction == "appendcomment")
                {
                    continue;
                }*/

                // 通过id值在读者记录中找到对应的<overdue>元素
                XmlNode nodeOverdue = readerdom.DocumentElement.SelectSingleNode("overdues/overdue[@id='" + item.ID + "']");
                if (nodeOverdue == null)
                {
                    strError = "ID为 '" + item.ID + "' 的<overdues/overdue>元素没有找到...";
                    return -1;
                }


                {
                    string strExistComment = DomUtil.GetAttr(nodeOverdue, "comment");

                    // 增补或修改注释
                    string strNewComment = item.NewComment;

                    // 处理追加标志
                    bool bAppend = true;
                    if (string.IsNullOrEmpty(strNewComment) == false
                        && strNewComment[0] == '<')
                    {
                        bAppend = false;
                        strNewComment = strNewComment.Substring(1);
                    }
                    else if (string.IsNullOrEmpty(strNewComment) == false
                        && strNewComment[0] == '>')
                    {
                        bAppend = true;
                        strNewComment = strNewComment.Substring(1);
                    }

                    if (String.IsNullOrEmpty(strNewComment) == false
                        && bAppend == true)
                    {
                        string strText = "";
                        if (String.IsNullOrEmpty(strExistComment) == false)
                            strText += strExistComment;
                        if (String.IsNullOrEmpty(strNewComment) == false)
                        {
                            if (String.IsNullOrEmpty(strText) == false)
                                strText += ";";
                            strText += strNewComment;
                        }

                        DomUtil.SetAttr(nodeOverdue, "comment", strText);
                        nChangedCount++;
                    }
                    else if (bAppend == false)
                    {
                        DomUtil.SetAttr(nodeOverdue, "comment", strNewComment);
                        nChangedCount++;    // BUG!!! 2011/12/1前少了这句话
                    }
                }
            }

            return nChangedCount;
        }
コード例 #8
0
ファイル: AppCirculation.cs プロジェクト: renyh1013/dp2
        // 根据AmerceItem数组,修改readerdom中的<amerce>元素中的价格price属性。
        // 为功能"modifyprice"服务。
        int ModifyPrice(ref XmlDocument readerdom,
            AmerceItem[] amerce_items,
            out string strError)
        {
            strError = "";
            int nChangedCount = 0;

            for (int i = 0; i < amerce_items.Length; i++)
            {
                AmerceItem item = amerce_items[i];

                // 遇到NewPrice域值为空的,直接跳过。
                // 这说明,不接受修改价格为完全空的字符串。
                if (String.IsNullOrEmpty(item.NewPrice) == true)
                {
                    if (String.IsNullOrEmpty(item.NewComment) == false)
                    {
                        strError = "不能用modifyprice子功能来单独修改注释(而不修改价格),请改用appendcomment和modifycomment子功能";
                        return -1;
                    }

                    continue;
                }

                // 通过id值在读者记录中找到对应的<overdue>元素
                XmlNode nodeOverdue = readerdom.DocumentElement.SelectSingleNode("overdues/overdue[@id='" + item.ID + "']");
                if (nodeOverdue == null)
                {
                    strError = "ID为 '" + item.ID + "' 的<overdues/overdue>元素没有找到...";
                    return -1;
                }

                string strOldPrice = DomUtil.GetAttr(nodeOverdue, "price");

                if (strOldPrice != item.NewPrice)
                {
                    // 修改price属性
                    DomUtil.SetAttr(nodeOverdue, "price", item.NewPrice);
                    nChangedCount++;

                    // 增补注释
                    string strNewComment = item.NewComment;
                    string strExistComment = DomUtil.GetAttr(nodeOverdue, "comment");

                    // 处理追加标志
                    bool bAppend = true;
                    if (string.IsNullOrEmpty(strNewComment) == false
                        && strNewComment[0] == '<')
                    {
                        bAppend = false;
                        strNewComment = strNewComment.Substring(1);
                    }
                    else if (string.IsNullOrEmpty(strNewComment) == false
                        && strNewComment[0] == '>')
                    {
                        bAppend = true;
                        strNewComment = strNewComment.Substring(1);
                    }

                    if (String.IsNullOrEmpty(strNewComment) == false
                        && bAppend == true)
                    {
                        string strText = "";
                        if (String.IsNullOrEmpty(strExistComment) == false)
                            strText += strExistComment;
                        if (String.IsNullOrEmpty(strNewComment) == false)
                        {
                            if (String.IsNullOrEmpty(strText) == false)
                                strText += ";";
                            strText += strNewComment;
                        }

                        DomUtil.SetAttr(nodeOverdue, "comment", strText);
                    }
                    else if (bAppend == false)
                    {
                        DomUtil.SetAttr(nodeOverdue, "comment", strNewComment);
                    }
                }
            }

            return nChangedCount;
        }