public static bool IsPriceCorrect(string strPrice) { if (string.IsNullOrEmpty(strPrice)) { return(false); } #if NO string strError = ""; CurrencyItem item = null; // 解析单个金额字符串。例如 CNY10.00 或 -CNY100.00/7 int nRet = PriceUtil.ParseSinglePrice(strPrice, out item, out strError); if (nRet == -1) { return(false); } return(true); #endif if (VerifyPrice(strPrice).Count > 0) { return(false); } return(true); }
internal static int ParsePriceString(string strPrice, out decimal value, out string strUnit, out string strError) { value = 0; strUnit = ""; strError = ""; if (string.IsNullOrEmpty(strPrice) == true) { return(0); } // 解析单个金额字符串。例如 CNY10.00 或 -CNY100.00/7 int nRet = PriceUtil.ParseSinglePrice(strPrice, out CurrencyItem item, out strError); if (nRet == -1) { return(-1); } strUnit = item.Prefix + item.Postfix; value = item.Value; return(0); }
public SumInfo GetSumInfo(List <RateItem> rate_table) { List <string> totalprices = new List <string>(); SumInfo info = new SumInfo(); info.Seller = this.Seller; foreach (OrderListItem item in _items) { info.BiblioCount++; info.CopyCount += item.Copy; totalprices.Add(item.TotalPrice); } if (totalprices.Count > 1) { string strError = ""; List <string> sum_prices = null; int nRet = PriceUtil.TotalPrice(totalprices, out sum_prices, out strError); if (nRet == -1) { info.TotalPrice = strError; } else { // Debug.Assert(sum_prices.Count == 1, ""); // info.TotalPrice = sum_prices[0]; info.TotalPrice = PriceUtil.JoinPriceString(sum_prices); } } else if (totalprices.Count == 1) { info.TotalPrice = totalprices[0]; } // 计算汇率 if (rate_table != null && string.IsNullOrEmpty(info.TotalPrice) == false) { try { string strRatePrice = RateItem.RatePrices( rate_table, info.TotalPrice); info.TotalPrice1 = strRatePrice; if (info.TotalPrice == info.TotalPrice1) { info.TotalPrice1 = ""; } } catch (Exception ex) { info.TotalPrice1 = ex.Message; } } return(info); }
static string ConcatPrice( IGrouping <string, ListViewItem> cl, int column_index) { // PrintOrderForm.RemoveChangedChar() string strList = ListViewUtil.GetItemText(cl.Aggregate((current, next) => { string s1 = ListViewUtil.GetItemText(current, column_index); string s2 = ListViewUtil.GetItemText(next, column_index); var r = new ListViewItem(); ListViewUtil.ChangeItemText(r, column_index, s1 + "," + s2); return(r); }), column_index); return(PriceUtil.TotalPrice(StringUtil.SplitList(strList))); }
static string ConcatLinePrice( IGrouping <string, PrintOrderForm.LineInfo> cl, string strFieldName) { // PrintOrderForm.RemoveChangedChar() string strList = (string)GetPropertyValue(cl.Aggregate((current, next) => { // TODO:单价应该乘以套数。或者还有期数也要乘上 string s1 = (string)GetPropertyValue(current, strFieldName); string s2 = (string)GetPropertyValue(next, strFieldName); var r = new PrintOrderForm.LineInfo(); SetPropertyValue(r, strFieldName, s1 + "," + s2); return(r); }), strFieldName); return(PriceUtil.TotalPrice(StringUtil.SplitList(strList))); }
// 为一列的字符串值增量 // 本方法只能应用在string值类型的列上,否则会抛出异常 // parameters: // createValue 如果列单元不存在,则采用此值初始设置 // incValue 如果列单元已经存在,则采用原来的值后面追加此值,修改回 public void IncCurrency( int nColumn, string createValue, string incValue) { EnsureCells(nColumn); if (cells[nColumn] == null) { cells[nColumn] = createValue; } else { object oldvalue = cells[nColumn]; if (oldvalue is string) { string v = (string)oldvalue; // 连接两个价格字符串 v = PriceUtil.JoinPriceString(v, incValue); string strSumPrices = ""; string strError = ""; // 将形如"-123.4+10.55-20.3"的价格字符串归并汇总 int nRet = PriceUtil.SumPrices(v, out strSumPrices, out strError); if (nRet == 0) { v = strSumPrices; } if (nRet == -1) { throw new Exception("汇总金额字符串 '" + v + "' 时出错:" + strError); } // v += incValue; cells[nColumn] = v; } else { throw (new Exception("列" + Convert.ToString(nColumn) + "类型必须为string")); } } }
static void Inc(Table table, string strEntry, int nColumn, string strPrice) { Line line = table.EnsureLine(strEntry); string strOldValue = (string)line[nColumn]; if (string.IsNullOrEmpty(strOldValue) == true) { line.SetValue(nColumn, strPrice); return; } // 连接两个价格字符串 string strPrices = PriceUtil.JoinPriceString(strOldValue, strPrice); string strError = ""; List <string> prices = null; // 将形如"-123.4+10.55-20.3"的价格字符串切割为单个的价格字符串,并各自带上正负号 // return: // -1 error // 0 succeed int nRet = PriceUtil.SplitPrices(strPrices, out prices, out strError); if (nRet == -1) { throw new Exception(strError); } string strResult = ""; nRet = PriceUtil.TotalPrice(prices, out strResult, out strError); if (nRet == -1) { throw new Exception(strError); } line.SetValue(nColumn, strResult); }
/* * // parameters: * // strRecord [in] 读者XML记录,或读者证条码号。 * // 如果是读者 XML 记录,第一字符是 '<',函数内代码可以据此进行判断。读者 XML 记录里面包含足够的标识字段即可,不要求包含所有字段 * // strPriceString [out] 金额字符串。一般为类似“CNY12.00”这样的形式 * // strRest [out] 扣款后的余额 * */ /// <summary> /// 从卡中心扣款 /// </summary> /// <param name="strRecord">账户标识,一般为读者 barcode </param> /// <param name="strPriceString">扣款金额字符串,单位:元。一般为类似“CNY12.00”这样的形式</param> /// <param name="strPassword">账户密码</param> /// <param name="strRest">扣款后的余额,单位:元,格式为 货币符号+金额数字部分,形如“CNY100.00”表示人民币 100元</param> /// <param name="strError">错误信息</param> /// <returns> /// <para>-2 密码不正确</para> /// <para>-1 出错(调用出错等特殊原因)</para> /// <para>0 扣款不成功(因为余额不足等普通原因)。注意 strError 中应当返回不成功的原因</para> /// <para>1 扣款成功</para> /// </returns> public int Deduct(string strRecord, string strPriceString, string strPassword, out string strRest, out string strError) { strRest = ""; strError = ""; if (strRecord.Trim().Substring(0, 1) == "<") { strError = "参数'strRecord'值不正确,不是正确的卡号"; return(-1); } // 第一个流程 扣款金额字符串 为空,需返回 账户余额 if (String.IsNullOrEmpty(strPriceString) == true) { strRest = ""; return(1); } // 处理带前缀的价格字符串 string strPrefix = ""; // 金额字符串前缀 string strValue = ""; // 金额字符串数字部分 string strPostfix = ""; // 金额字符串后缀 int nRet = PriceUtil.ParsePriceUnit(strPriceString, out strPrefix, out strValue, out strPostfix, out strError); if (nRet == -1) { return(-1); } // TODO: 这里应该加入真实的扣款代码。 // 一般是要访问卡中心的 SQL 数据库,找到该读者的记录,对金额字段进行扣款修改,然后返回扣款后账户余额 // 可用的参数:经过前面的准备,这里 strPrefix 内容是货币代码;strValue 内容是要扣款的数字金额值。strRecord 内容是读者证条码号;strPassword 是读者(在前端扣款界面)输入的密码 // 扣款成功,返回扣款后的余额。注意这只是一行简单的示范代码 strRest = strPrefix + "0.00"; return(1); }
// 校验价格 public static List <string> VerifyPrice(string strPrice) { List <string> errors = new List <string>(); // 解析单个金额字符串。例如 CNY10.00 或 -CNY100.00/7 int nRet = PriceUtil.ParseSinglePrice(strPrice, out CurrencyItem item, out string strError); if (nRet == -1) { errors.Add(strError); } // 2020/7/8 // 检查货币字符串中是否出现了字母以外的字符 if (string.IsNullOrEmpty(item.Postfix) == false) { errors.Add($"金额字符串 '{strPrice}' 中出现了后缀 '{item.Postfix}' ,这很不常见,一般意味着错误"); } string error1 = VerifyPricePrefix(item.Prefix); if (error1 != null) { errors.Add(error1); } string new_value = StringUtil.ToDBC(strPrice); if (new_value.IndexOfAny(new char[] { '(', ')' }) != -1) { errors.Add("价格字符串中不允许出现括号 '" + strPrice + "'"); } if (new_value.IndexOf(',') != -1) { errors.Add("价格字符串中不允许出现逗号 '" + strPrice + "'"); } return(errors); }
public static DoubleCurrencyItem Parse(string strText) { string strError = ""; string strPrefix = ""; string strValue = ""; string strPostfix = ""; int nRet = PriceUtil.ParsePriceUnit(strText, out strPrefix, out strValue, out strPostfix, out strError); if (nRet == -1) { throw new Exception(strError); } double value = 0; try { value = Convert.ToDouble(strValue); } catch { strError = "数字 '" + strValue + "' 格式不正确"; throw new Exception(strError); } DoubleCurrencyItem item = new DoubleCurrencyItem(); item.Prefix = strPrefix; item.Postfix = strPostfix; item.Value = value; return(item); }
// 将形如"-CNY123.4+USD10.55-20.3"的价格字符串计算汇率 // parameters: public static string RatePrices( List <RateItem> rate_table, string strPrices) { string strError = ""; strPrices = strPrices.Trim(); if (String.IsNullOrEmpty(strPrices) == true) { return(""); } List <string> prices = null; // 将形如"-123.4+10.55-20.3"的价格字符串切割为单个的价格字符串,并各自带上正负号 // return: // -1 error // 0 succeed int nRet = PriceUtil.SplitPrices(strPrices, out prices, out strError); if (nRet == -1) { throw new Exception(strError); } List <string> changed_prices = new List <string>(); foreach (string price in prices) { CurrencyItem item = CurrencyItem.Parse(price); RateItem rate = FindBySource(rate_table, item.Prefix, item.Postfix); if (rate == null) { changed_prices.Add(price); continue; } CurrencyItem result = rate.Exchange(item); changed_prices.Add(result.ToString()); } List <string> results = new List <string>(); // 汇总价格 // 货币单位不同的,互相独立 // return: // -1 error // 0 succeed nRet = PriceUtil.TotalPrice(changed_prices, out results, out strError); if (nRet == -1) { throw new Exception(strError); } #if NO StringBuilder text = new StringBuilder(); for (int i = 0; i < results.Count; i++) { string strOnePrice = results[i]; if (String.IsNullOrEmpty(strOnePrice) == true) { continue; } if (strOnePrice[0] == '+') { text.Append("+" + strOnePrice.Substring(1)); } else if (strOnePrice[0] == '-') { text.Append("-" + strOnePrice.Substring(1)); } else { text.Append("+" + strOnePrice); // 缺省为正数 } } return(text.ToString().TrimStart(new char[] { '+' })); #endif return(PriceUtil.JoinPriceString(results)); }
/// <summary> /// 结束前的校验 /// </summary> /// <param name="strError">返回错误信息</param> /// <returns>-1: 出错; 0: 没有错误</returns> internal override int FinishVerify(out string strError) { strError = ""; int nRet = 0; // TODO: 将来这里要允许使用整个 location 字符串,而不仅仅是馆代码,来发起条码号校验 string strLocation = this.entityEditControl_editing.LocationString; string strLibraryCode = Global.GetLibraryCode(StringUtil.GetPureLocation(strLocation)); string strBarcode = this.entityEditControl_editing.Barcode; // 检查册条码号形式是否合法 if (String.IsNullOrEmpty(strBarcode) == false && // 2009/2/23 this.EntityControl != null && this.EntityControl.NeedVerifyItemBarcode == true) { // 形式校验条码号 // return: // -2 服务器没有配置校验方法,无法校验 // -1 error // 0 不是合法的条码号 // 1 是合法的读者证条码号 // 2 是合法的册条码号 nRet = this.EntityControl.DoVerifyBarcode( string.IsNullOrEmpty(Program.MainForm.BarcodeValidation) ? strLibraryCode : strLocation, // 2019/7/12 strBarcode, out strError); if (nRet == -1) { goto ERROR1; } // 输入的条码格式不合法 if (nRet == 0) { strError = "您输入的条码 " + strBarcode + " 格式不正确(" + strError + ")。请重新输入。"; goto ERROR1; } // 实际输入的是读者证条码号 if (nRet == 1) { strError = "您输入的条码号 " + strBarcode + " 是读者证条码号。请输入册条码号。"; goto ERROR1; } // 对于服务器没有配置校验功能,但是前端发出了校验要求的情况,警告一下 if (nRet == -2) { MessageBox.Show(this, "警告:前端册管理窗开启了校验条码功能,但是服务器端缺乏相应的脚本函数,无法校验条码。\r\n\r\n若要避免出现此警告对话框,请关闭前端册管理窗校验功能"); } } // 馆藏地点字符串里面不能有星号 // string strLocation = this.entityEditControl_editing.LocationString; if (strLocation.IndexOf("*") != -1) { strError = "馆藏地点字符串中不允许出现字符 '*'"; goto ERROR1; } // 价格字符串中不允许出现 @ string strPrice = this.entityEditControl_editing.Price; if (strPrice.IndexOf("@") != -1) { strError = "价格字符串中不允许出现字符 '@'"; goto ERROR1; } if (string.IsNullOrEmpty(strPrice) == false) { CurrencyItem item = null; // 解析单个金额字符串。例如 CNY10.00 或 -CNY100.00/7 nRet = PriceUtil.ParseSinglePrice(strPrice, out item, out strError); if (nRet == -1) { strError = "价格字符串格式不合法: " + strError; goto ERROR1; } } string strIssueDbName = ""; if (string.IsNullOrEmpty(this.BiblioDbName) == false) { strIssueDbName = Program.MainForm.GetIssueDbName(this.BiblioDbName); } if (string.IsNullOrEmpty(strIssueDbName) == false) { // 2014/10/23 if (string.IsNullOrEmpty(this.entityEditControl_editing.PublishTime) == false) { // 检查出版时间范围字符串是否合法 // 如果使用单个出版时间来调用本函数,也是可以的 // return: // -1 出错 // 0 正确 nRet = LibraryServerUtil.CheckPublishTimeRange(this.entityEditControl_editing.PublishTime, out strError); if (nRet == -1) { goto ERROR1; } } // 2014/10/23 if (string.IsNullOrEmpty(this.entityEditControl_editing.Volume) == false) { List <VolumeInfo> infos = null; nRet = VolumeInfo.BuildVolumeInfos(this.entityEditControl_editing.Volume, out infos, out strError); if (nRet == -1) { strError = "卷期字符串 '" + this.entityEditControl_editing.Volume + "' 格式错误: " + strError; goto ERROR1; } } } return(0); ERROR1: return(-1); }
// 将两个订购XML片断合并 // 当旧的和新的都是全管辖范围内,就允许新的全部替换旧的;否则只允许替换<distribute>元素内容 // parameters: // strLibraryCodeList 当前用户管辖的分馆代码列表 // strMergedXml [out]范围订购<root>元素的InnerXml // return: // -1 出错 // 0 正常 // 1 发生了超越范围的修改 public static int MergeOrderNode(XmlNode exist_node, XmlNode new_node, string strLibraryCodeList, out string strMergedXml, out string strError) { strError = ""; strMergedXml = ""; int nRet = 0; Debug.Assert(SessionInfo.IsGlobalUser(strLibraryCodeList) == false, "全局用户不应调用函数 MergeOrderNode()"); string strExistDistribute = DomUtil.GetElementText(exist_node, "distribute"); string strNewDistribute = DomUtil.GetElementText(new_node, "distribute"); bool bExistControlled = true; bool bNewControlled = true; if (string.IsNullOrEmpty(strExistDistribute) == false) { // 观察一个馆藏分配字符串,看看是否在当前用户管辖范围内 // return: // -1 出错 // 0 超过管辖范围。strError中有解释 // 1 在管辖范围内 nRet = DistributeInControlled(strExistDistribute, strLibraryCodeList, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { bExistControlled = false; } } if (string.IsNullOrEmpty(strNewDistribute) == false) { // 观察一个馆藏分配字符串,看看是否在当前用户管辖范围内 // return: // -1 出错 // 0 超过管辖范围。strError中有解释 // 1 在管辖范围内 nRet = DistributeInControlled(strNewDistribute, strLibraryCodeList, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { bNewControlled = false; } } if (bExistControlled == true && bNewControlled == true) { // 当旧的和新的都是全管辖范围内,就允许新的全部替换旧的 strMergedXml = new_node.InnerXml; return(0); } string strExistCopy = DomUtil.GetElementText(exist_node, "copy"); string strExistPrice = DomUtil.GetElementText(exist_node, "price"); string strChangedCopy = DomUtil.GetElementText(new_node, "copy"); string strChangedPrice = DomUtil.GetElementText(new_node, "price"); // 比较两个复本字符串 { ParseOldNewValue(strExistCopy, out string strExistOldValue, out string strExistNewValue); ParseOldNewValue(strChangedCopy, out string strChangedOldValue, out string strChangedNewValue); if (strExistOldValue != strChangedOldValue) { strError = "订购套数(方括号左边的部分)不允许修改。(原来='" + strExistCopy + "',新的='" + strChangedCopy + "')"; return(1); } // 检查验收套数的改变,是否正好和distribute字符串内的改变吻合 } // 比较两个价格字符串 { ParseOldNewValue(strExistPrice, out string strExistOldValue, out string strExistNewValue); ParseOldNewValue(strChangedPrice, out string strChangedOldValue, out string strChangedNewValue); // 避免用 == 判断。用 IsEqual 判断,可以把 CNY10.00 和 10.00 视作等同 if (PriceUtil.IsEqual(strExistOldValue, strChangedOldValue) == false) { strError = "订购价(方括号左边的部分)不允许修改。(原来='" + strExistPrice + "',新的='" + strChangedPrice + "')"; return(1); } if (PriceUtil.IsEqual(strExistNewValue, strChangedNewValue) == false) { strError = "验收价(方括号中的部分)不允许修改。(原来='" + strExistPrice + "',新的='" + strChangedPrice + "')"; return(1); } } LocationCollection new_locations = new LocationCollection(); nRet = new_locations.Build(strNewDistribute, out strError); if (nRet == -1) { strError = "馆藏分配字符串 '" + strNewDistribute + "' 格式不正确"; return(-1); } LocationCollection exist_locations = new LocationCollection(); nRet = exist_locations.Build(strExistDistribute, out strError); if (nRet == -1) { strError = "馆藏分配字符串 '" + strExistDistribute + "' 格式不正确"; return(-1); } if (exist_locations.Count != new_locations.Count) { strError = "馆藏分配事项个数发生了改变(原来=" + exist_locations.Count.ToString() + ",新的=" + new_locations.Count.ToString() + ")"; return(1); } for (int i = 0; i < exist_locations.Count; i++) { Location exist_location = exist_locations[i]; Location new_location = new_locations[i]; if (exist_location.Name != new_location.Name) { // 进一步检查是否馆代码部分改变了 // 解析 LibraryApplication.ParseCalendarName(exist_location.Name, out string strCode1, out string strPureName); LibraryApplication.ParseCalendarName(new_location.Name, out string strCode2, out strPureName); // 只要馆代码部分不改变即可 if (strCode1 != strCode2) { strError = "第 " + (i + 1).ToString() + " 个馆藏分配事项的名字(的馆代码部分)发生改变 (原来='" + exist_location.Name + "',新的='" + new_location.Name + "')"; return(1); } } if (exist_location.RefID != new_location.RefID) { // 解析 LibraryApplication.ParseCalendarName(exist_location.Name, out string strLibraryCode, out string strPureName); if (StringUtil.IsInList(strLibraryCode, strLibraryCodeList) == false) { strError = "馆代码 '" + strLibraryCode + "' 不在范围 '" + strLibraryCodeList + "' 内,不允许进行收登操作。"; return(1); } } } // 将旧的XML片断装入,只修改里面的三个元素值。这样可以保证三个元素以外的原记录内容不被修改 XmlDocument dom = new XmlDocument(); try { dom.LoadXml(exist_node.OuterXml); } catch (Exception ex) { strError = "exist_node.OuterXml装入XMLDOM失败: " + ex.Message; return(-1); } DomUtil.SetElementText(dom.DocumentElement, "copy", strChangedCopy); DomUtil.SetElementText(dom.DocumentElement, "price", strChangedPrice); DomUtil.SetElementText(dom.DocumentElement, "distribute", strNewDistribute); strMergedXml = dom.DocumentElement.InnerXml; return(0); }
// 根据读者记录中 overdue 内容填充 line 的各个成员 static void FillRecordByOverdue(XmlElement overdue, string strReaderBarcode, string strNewPrice, AmerceOper line, StringBuilder debugInfo) { if (overdue == null) { return; } string strError = ""; line.AmerceRecPath = ""; line.Action = "modifyprice"; try { line.ReaderBarcode = strReaderBarcode; line.ItemBarcode = overdue.GetAttribute("barcode"); line.ID = overdue.GetAttribute("id"); // 2016/12/6 // 变化的金额 string strOldPrice = overdue.GetAttribute("price"); List <string> prices = new List <string>(); if (string.IsNullOrEmpty(strNewPrice) == false) { prices.Add(strNewPrice); } if (string.IsNullOrEmpty(strOldPrice) == false) { prices.Add("-" + strOldPrice); } string strResult = ""; int nRet = PriceUtil.TotalPrice(prices, out strResult, out strError); if (nRet == -1) { // return -1; if (debugInfo != null) { debugInfo.Append("FillRecordByOverdue() TotalPrice() 解析金额字符串 '" + StringUtil.MakePathList(prices) + "' 时出错(已被当作 0 处理): " + strError + "\r\n"); } return; } nRet = ParsePriceString(strResult, out decimal value, out string strUnit, out strError); if (nRet == -1) { if (debugInfo != null) { debugInfo.Append("FillRecordByOverdue() 解析金额字符串 '" + strResult + "' 时出错(已被当作 0 处理): " + strError + "\r\n"); } line.Unit = ""; line.Price = 0; } else { line.Unit = strUnit; line.Price = value; } line.Reason = overdue.GetAttribute("reason"); } catch (Exception ex) { if (debugInfo != null) { debugInfo.Append("FillRecordByOverdue() 出现异常: " + ExceptionUtil.GetExceptionText(ex) + "\r\n"); } } }
internal static int ParsePriceString(string strPrice, out long value, out string strUnit, out string strError) { value = 0; strUnit = ""; strError = ""; if (string.IsNullOrEmpty(strPrice) == true) { return(0); } #if NO string strPrefix = ""; string strValue = ""; string strPostfix = ""; // 分析价格参数 // 允许前面出现+ -号 // return: // -1 出错 // 0 成功 int nRet = PriceUtil.ParsePriceUnit(strPrice, out strPrefix, out strValue, out strPostfix, out strError); if (nRet == -1) { return(-1); } strUnit = strPrefix + strPostfix; decimal v = 0; if (decimal.TryParse(strValue, out v) == false) { strError = "金额字符串 '" + strPrice + "' 中数字部分 '" + strValue + "' 格式不正确"; return(-1); } #endif CurrencyItem item = null; // 解析单个金额字符串。例如 CNY10.00 或 -CNY100.00/7 int nRet = PriceUtil.ParseSinglePrice(strPrice, out item, out strError); if (nRet == -1) { return(-1); } strUnit = item.Prefix + item.Postfix; try { value = (long)(item.Value * 100); } catch (Exception ex) { // 2016/3/31 strError = "元值 '" + item.Value.ToString() + "' 折算为分值的时候出现异常:" + ex.Message; return(-1); } return(0); }
object AddValue(ColumnDataType datatype, object o1, object o2) { if (o1 == null && o2 == null) { return(null); } if (o1 == null) { return(o2); } if (o2 == null) { return(o1); } if (datatype == ColumnDataType.Auto) { if (o1 is Int64) { return((Int64)o1 + Convert.ToInt64(o2)); // 2016/11/24 } if (o1 is Int32) { return((Int32)o1 + (Int32)o2); } if (o1 is double) { #if NO if (o2 is long) { return((double)o1 + Convert.ToDouble(o2)); } return((double)o1 + (double)o2); #endif return((double)o1 + Convert.ToDouble(o2)); } if (o1 is decimal) { return((decimal)o1 + (decimal)o2); } if (o1 is string) { return((string)o1 + (string)o2); } throw new Exception("无法支持的 Auto 类型累加 o1 type=" + o1.GetType().ToString() + ", o2 type=" + o2.GetType().ToString()); } if (datatype == ColumnDataType.Number) { if (o1 is Int64) { return((Int64)o1 + (Int64)o2); } if (o1 is Int32) { return((Int32)o1 + (Int32)o2); } if (o1 is double) { return((double)o1 + (double)o2); } if (o1 is decimal) { return((decimal)o1 + (decimal)o2); } if (o1 is string) // 2015/7/16 { Int64 v1 = 0; Int64 v2 = 0; Int64.TryParse(o1 as string, out v1); Int64.TryParse(o2 as string, out v2); return((v1 + v2).ToString()); } throw new Exception("无法支持的 Number 类型累加 o1 type=" + o1.GetType().ToString() + ", o2 type=" + o2.GetType().ToString()); } if (datatype == ColumnDataType.String) { if (o1 is string) { return((string)o1 + (string)o2); } throw new Exception("无法支持的 String 类型累加 o1 type=" + o1.GetType().ToString() + ", o2 type=" + o2.GetType().ToString()); } if (datatype == ColumnDataType.Price) // 100倍金额整数 { return((Int64)o1 + (Int64)o2); } if (datatype == ColumnDataType.PriceDouble) // double,用来表示金额。也就是最多只有两位小数部分 -- 注意,有累计误差问题,以后建议废止 { return((double)o1 + (double)o2); } if (datatype == ColumnDataType.PriceDecimal) // decimal,用来表示金额。 { return((decimal)o1 + (decimal)o2); } if (datatype == ColumnDataType.Currency) { #if NO // 这一句容易发现列 数据类型 的错误 return(PriceUtil.JoinPriceString((string)o1, (string)o2)); #endif return(PriceUtil.Add((string)o1, (string)o2)); #if NO // 这一句更健壮一些 return(PriceUtil.JoinPriceString(Convert.ToString(o1), Convert.ToString(o2))); #endif } throw new Exception("无法支持的 " + datatype.ToString() + " 类型累加 o1 type=" + o1.GetType().ToString() + ", o2 type=" + o2.GetType().ToString()); }
// 将 OrderStorage 对象的信息合并到本对象 public void Merge(OrderStore order) { string strError = ""; if (this.Orders == null) { this.Orders = new List <OrderStore>(); } if (this.Orders.IndexOf(order) != -1) { throw new Exception("order 对象已经在 Orders 中存在了,不允许重复合并"); } this.Orders.Add(order); XmlDocument dom = new XmlDocument(); dom.LoadXml(order.Xml); Hashtable value_table = GetValues(order); string strSeller = (string)value_table["seller"]; if (string.IsNullOrEmpty(this.Seller)) { this.Seller = strSeller; } else { if (this.Seller != strSeller) { throw new Exception("this.Seller '" + this.Seller + "' 和即将合并的 order.Seller '" + strSeller + "' 不一致"); } } string strCatalogNo = (string)value_table["catalogNo"]; if (string.IsNullOrEmpty(this.CatalogNo)) { this.CatalogNo = strCatalogNo; } else { if (this.CatalogNo != strCatalogNo) { throw new Exception("this.CatalogNo '" + this.CatalogNo + "' 和即将合并的 order.CatalogNo '" + strCatalogNo + "' 不一致"); } } string strPrice = (string)value_table["price"]; if (string.IsNullOrEmpty(this.Price)) { this.Price = strPrice; } else { if (this.Price != strPrice) { throw new Exception("this.Price '" + this.Price + "' 和即将合并的 order.Price '" + strPrice + "' 不一致"); } } string strAcceptPrice = (string)value_table["acceptPrice"]; if (string.IsNullOrEmpty(this.AcceptPrice)) { this.AcceptPrice = strAcceptPrice; } else { if (this.AcceptPrice != strAcceptPrice) { throw new Exception("this.AcceptPrice '" + this.AcceptPrice + "' 和即将合并的 order.AcceptPrice '" + strAcceptPrice + "' 不一致"); } } string strIssueCount = (string)value_table["issueCount"]; if (string.IsNullOrEmpty(this.IssueCount)) { this.IssueCount = strIssueCount; } else { if (this.IssueCount != strIssueCount) { throw new Exception("this.IssueCount '" + this.IssueCount + "' 和即将合并的 order.IssueCount '" + strIssueCount + "' 不一致"); } } string strRange = (string)value_table["range"]; if (string.IsNullOrEmpty(this.Range)) { this.Range = strRange; } else { if (this.Range != strRange) { throw new Exception("this.Range '" + this.Range + "' 和即将合并的 order.Range '" + strRange + "' 不一致"); } } int nSubCopy = (int)value_table["subcopy"]; if (this.SubCopy == 0) { this.SubCopy = nSubCopy; } else { if (this.SubCopy != nSubCopy) { throw new Exception("this.SubCopy '" + this.SubCopy + "' 和即将合并的 order.SubCopy '" + nSubCopy + "' 不一致"); } } string strSellerAddress = (string)value_table["sellerAddress"]; if (string.IsNullOrEmpty(this.SellerAddress)) { this.SellerAddress = strSellerAddress; } // 以下是需要累加的字段 if (this.MergeComment == null) { this.MergeComment = new List <string>(); } int nCopy = (int)value_table["copy"]; this.Copy += nCopy; string strSource = DomUtil.GetElementText(dom.DocumentElement, "source"); string strMergeComment = strSource + ", " + nCopy.ToString() + "册 (" + order.RecPath + ")"; this.MergeComment.Add(strMergeComment); int nIssueCount = 1; if (string.IsNullOrEmpty(strIssueCount) == false) { Int32.TryParse(strIssueCount, out nIssueCount); } // 汇总价格 List <string> totalprices = new List <string>(); if (string.IsNullOrEmpty(this.TotalPrice) == false) { totalprices.Add(this.TotalPrice); } string strTotalPrice = ""; if (String.IsNullOrEmpty(strPrice) == false) { int nRet = PriceUtil.MultiPrice(strPrice, nCopy * nIssueCount, out strTotalPrice, out strError); if (nRet == -1) { strError = "原始数据事项 " + order.RecPath + " 内价格字符串 '" + strPrice + "' 格式不正确: " + strError; throw new Exception(strError); } totalprices.Add(strTotalPrice); } if (totalprices.Count > 1) { List <string> sum_prices = null; int nRet = PriceUtil.TotalPrice(totalprices, out sum_prices, out strError); if (nRet == -1) { throw new Exception(strError); } // Debug.Assert(sum_prices.Count == 1, ""); // this.TotalPrice = sum_prices[0]; this.TotalPrice = PriceUtil.JoinPriceString(sum_prices); } else if (totalprices.Count == 1) { this.TotalPrice = totalprices[0]; } // 汇总注释 if (this.Comments == null) { this.Comments = new List <string>(); } string strComment = DomUtil.GetElementText(dom.DocumentElement, "comment"); if (String.IsNullOrEmpty(strComment) == false) { this.Comments.Add(strComment + " @" + order.RecPath); } // 汇总馆藏分配字符串 string strDistribute = DomUtil.GetElementText(dom.DocumentElement, "distribute"); if (String.IsNullOrEmpty(strDistribute) == false) { if (String.IsNullOrEmpty(this.Distribute) == true) { this.Distribute = strDistribute; } else { string strLocationString = ""; int nRet = LocationCollection.MergeTwoLocationString(this.Distribute, strDistribute, false, out strLocationString, out strError); if (nRet == -1) { throw new Exception(strError); } this.Distribute = strLocationString; } } }
private void button_currency_sum_Click(object sender, EventArgs e) { List <string> prices = new List <string>(this.textBox_currency_source.Lines); this.textBox_currency_target.Text = PriceUtil.TotalPrice(prices); }
public static string SumPrice <T>(this IEnumerable <T> collection, Func <T, string> selector) { return(collection.Aggregate("" /*start with an empty MyClass*/, (a, b) => PriceUtil.Add(a, selector(b)))); }
/* * ~~~~~~~ * 乐山师院数据来源多,以前的种价格字段格式著录格式多样,有“CNY25.00元”、 * “25.00”、“¥25.00元”、“¥25.00”、“CNY25.00”、“cny25.00”、“25.00 * 元”等等,现在他们确定以后全采用“CNY25.00”格式著录。 * CALIS中,许可重复010$d来表达价格实录和获赠或其它币种价格。所以,可能乐山 * 师院也有少量的此类重复价格子字段的数据。 * 为省成本,批处理或册信息编辑窗中,建议只管一个价格字段,别的都不管(如果 * 没有价格字段,则转换为空而非零)。 * 转换时,是否可以兼顾到用中文全角输入的数字如“25.00”或小数点是中文 * 全解但标点选择的是英文标点如“.”? * * ~~~~ * 处理步骤: * 1) 全部字符转换为半角 * 2) 抽出纯数字部分 * 3) 观察前缀或者后缀,如果有CNY cny ¥ 元等字样,可以确定为人民币。 * 前缀和后缀完全为空,也可确定为人民币。 * 否则,保留原来的前缀。 * */ // 正规化价格字符串 public static string CanonicalizePrice(string strPrice, bool bForceCNY) { // 全角字符变换为半角 strPrice = Global.ConvertQuanjiaoToBanjiao(strPrice); if (bForceCNY == true) { // 提取出纯数字 string strPurePrice = PriceUtil.GetPurePrice(strPrice); return("CNY" + strPurePrice); } string strPrefix = ""; string strValue = ""; string strPostfix = ""; string strError = ""; int nRet = Global.ParsePriceUnit(strPrice, out strPrefix, out strValue, out strPostfix, out strError); if (nRet == -1) { return(strPrice); // 无法parse } bool bCNY = false; strPrefix = strPrefix.Trim(); strPostfix = strPostfix.Trim(); if (String.IsNullOrEmpty(strPrefix) == true && String.IsNullOrEmpty(strPostfix) == true) { bCNY = true; goto DONE; } if (strPrefix.IndexOf("CNY") != -1 || strPrefix.IndexOf("cny") != -1 || strPrefix.IndexOf("CNY") != -1 || strPrefix.IndexOf("cny") != -1 || strPrefix.IndexOf('¥') != -1) { bCNY = true; goto DONE; } if (strPostfix.IndexOf("元") != -1) { bCNY = true; goto DONE; } DONE: // 人民币 if (bCNY == true) { return("CNY" + strValue); } // 其他货币 return(strPrefix + strValue + strPostfix); }
// 输出 RML 格式的表格 // 本函数负责写入 <table> 元素 // parameters: // nTopLines 顶部预留多少行 void OutputRmlTable <T>( IEnumerable <T> data_reader, object sum, XmlTextWriter writer, int nMaxLines = -1) { // StringBuilder strResult = new StringBuilder(4096); int i, j; #if NO if (nMaxLines == -1) { nMaxLines = table.Count; } #endif writer.WriteStartElement("table"); WriteAttributeString(writer, "class", "table"); writer.WriteStartElement("thead"); writer.WriteStartElement("tr"); int nEvalCount = 0; // 具有 eval 的栏目个数 for (j = 0; j < this.Columns.Count; j++) { PrintColumn000 column = this.Columns[j]; if (column.Colspan == 0) { continue; } if (string.IsNullOrEmpty(column.Eval) == false) { nEvalCount++; } writer.WriteStartElement("th"); if (string.IsNullOrEmpty(column.CssClass) == false) { WriteAttributeString(writer, "class", column.CssClass); } if (column.Colspan > 1) { WriteAttributeString(writer, "colspan", column.Colspan.ToString()); } WriteString(writer, column.Title); writer.WriteEndElement(); // </th> } writer.WriteEndElement(); // </tr> writer.WriteEndElement(); // </thead> // 合计数组 object[] sums = null; // 2008/12/1 new changed if (this.SumLine) { sums = new object[this.Columns.Count]; for (i = 0; i < sums.Length; i++) { sums[i] = null; } } NumberFormatInfo nfi = new CultureInfo("zh-CN", false).NumberFormat; nfi.NumberDecimalDigits = 2; writer.WriteStartElement("tbody"); // Jurassic.ScriptEngine engine = null; if (nEvalCount > 0 && engine == null) { engine = new Jurassic.ScriptEngine(); engine.EnableExposedClrTypes = true; } int nLineCount = 0; var handle = data_reader.GetEnumerator(); // 内容行循环 for (i = 0; ; i++) // i < Math.Min(nMaxLines, table.Count) { if (handle.MoveNext() == false) { break; } nLineCount++; #if NO if (table.HasRows == false) { break; } #endif // Line line = table[i]; if (engine != null) { engine.SetGlobalValue("line", data_reader); } string strLineCssClass = "content"; #if NO if (report.OutputLine != null) { OutputLineEventArgs e = new OutputLineEventArgs(); e.Line = line; e.Index = i; e.LineCssClass = strLineCssClass; report.OutputLine(this, e); if (e.Output == false) { continue; } strLineCssClass = e.LineCssClass; } #endif // strResult.Append("<tr class='" + strLineCssClass + "'>\r\n"); writer.WriteStartElement("tr"); WriteAttributeString(writer, "class", strLineCssClass); // 列循环 for (j = 0; j < this.Columns.Count; j++) { PrintColumn000 column = this.Columns[j]; if (column.ColumnNumber < -1) { throw (new Exception("PrintColumn对象ColumnNumber列尚未初始化,位置" + Convert.ToString(j))); } string strText = ""; if (column.ColumnNumber != -1) { // Debug.Assert(column.ColumnNumber < data_reader.FieldCount, ""); if (string.IsNullOrEmpty(column.Eval) == false) { // engine.SetGlobalValue("cell", line.GetObject(column.ColumnNumber)); engine.SetGlobalValue("rowNumber", nLineCount.ToString()); engine.SetGlobalValue("currency", new PriceUtil()); strText = engine.Evaluate(column.Eval).ToString(); } #if NO else if (column.DataType == ColumnDataType.PriceDouble) { if (data_reader.IsDBNull(column.ColumnNumber) == true) { strText = column.DefaultValue; } else { double v = data_reader.GetDouble(column.ColumnNumber); strText = v.ToString("N", nfi); } } else if (column.DataType == ColumnDataType.PriceDecimal) { if (data_reader.IsDBNull(column.ColumnNumber) == true) { strText = column.DefaultValue; } else { decimal v = data_reader.GetDecimal(column.ColumnNumber); strText = v.ToString("N", nfi); } } else if (column.DataType == ColumnDataType.PriceDecimal) { if (data_reader.IsDBNull(column.ColumnNumber) == true) { strText = column.DefaultValue; } else { decimal v = data_reader.GetDecimal(column.ColumnNumber); strText = v.ToString("N", nfi); } } else if (column.DataType == ColumnDataType.Price) { // Debug.Assert(false, ""); if (data_reader.IsDBNull(column.ColumnNumber) == true) { strText = column.DefaultValue; // 2005/5/26 } else { strText = data_reader.GetString(column.ColumnNumber); // } } else if (column.DataType == ColumnDataType.String) { // strText = data_reader.GetString(column.ColumnNumber/*, column.DefaultValue*/); // 2014/8/28 object o = data_reader.GetValue(column.ColumnNumber); if (o != null) { strText = o.ToString(); } else { strText = ""; } } #endif else { TryGetFieldValue(handle.Current, column.CssClass, out object o); // (column.ColumnNumber); if (o != null) { strText = o.ToString(); } else { strText = ""; } } } else { // strText = data_reader.GetString(0); // line.Entry; } writer.WriteStartElement(j == 0 ? "th" : "td"); if (string.IsNullOrEmpty(column.CssClass) == false) { WriteAttributeString(writer, "class", column.CssClass); } WriteString(writer, strText); writer.WriteEndElement(); // </td> if (this.SumLine == true && column.Sum == true && column.ColumnNumber != -1) { string strDebugInfo = ""; try { // if (column.DataType != DataType.Currency) { // if (column.ColumnNumber < data_reader.FieldCount) // v = data_reader.GetValue(column.ColumnNumber); TryGetFieldValue(handle.Current, column.CssClass, out object v); if (sums[j] == null) { sums[j] = v; } else { strDebugInfo = GetDebugInfo(column.DataType, sums[j], v); sums[j] = AddValue(column.DataType, sums[j], v); // sums[j] = ((decimal)sums[j]) + v; } } } catch (Exception ex) // 俘获可能因字符串转换为整数抛出的异常 { throw new Exception("在累加 行 " + i.ToString() + " 列 " + column.ColumnNumber.ToString() + " 值的时候,出现异常(strDebugInfo='" + strDebugInfo + "'): " + ExceptionUtil.GetAutoText(ex)); } } } // strResult.Append("</tr>\r\n"); writer.WriteEndElement(); // </tr> } writer.WriteEndElement(); // </tbody> if (sum != null) { writer.WriteStartElement("tfoot"); writer.WriteStartElement("tr"); WriteAttributeString(writer, "class", "sum"); for (j = 0; j < this.Columns.Count; j++) { PrintColumn000 column = this.Columns[j]; string strText = ""; if (j == 0) { strText = "合计(" + nLineCount.ToString() + "行)"; } else if (column.Sum == true) { if (string.IsNullOrEmpty(column.Eval) == false) { engine.SetGlobalValue("currency", new PriceUtil()); strText = engine.Evaluate(column.Eval).ToString(); } else if (column.Sum == true) { TryGetFieldValue(sum, column.CssClass, out object o); // (column.ColumnNumber); if (o != null) { strText = o.ToString(); } else { strText = ""; } } } writer.WriteStartElement(j == 0 ? "th" : "td"); if (string.IsNullOrEmpty(column.CssClass) == false) { WriteAttributeString(writer, "class", column.CssClass); } WriteString(writer, strText); writer.WriteEndElement(); // </td> } writer.WriteEndElement(); // </tr> writer.WriteEndElement(); // </tfoot> } else if (this.SumLine == true) { /* * SumLineReader sum_line = null; * if (engine != null) * { * // 准备 Line 对象 * sum_line = new SumLineReader(); * sum_line.FieldValues = sums; * sum_line.Read(); * engine.SetGlobalValue("line", sum_line); * engine.SetGlobalValue("rowNumber", ""); * } */ // strResult.Append("<tr class='sum'>\r\n"); writer.WriteStartElement("tfoot"); writer.WriteStartElement("tr"); WriteAttributeString(writer, "class", "sum"); for (j = 0; j < this.Columns.Count; j++) { PrintColumn000 column = this.Columns[j]; string strText = ""; if (j == 0) { strText = "合计(" + nLineCount.ToString() + "行)"; } else if (column.Sum == true) { if (string.IsNullOrEmpty(column.Eval) == false) { engine.SetGlobalValue("currency", new PriceUtil()); strText = engine.Evaluate(column.Eval).ToString(); } else if (column.Sum == true && sums[j] != null) { if (column.DataType == ColumnDataType.PriceDouble) { strText = ((double)sums[j]).ToString("N", nfi); } else if (column.DataType == ColumnDataType.PriceDecimal) { strText = ((decimal)sums[j]).ToString("N", nfi); } else if (column.DataType == ColumnDataType.Price) { strText = Int64ToPrice((Int64)sums[j]); } else { strText = Convert.ToString(sums[j]); } if (column.DataType == ColumnDataType.Currency) { // 汇总价格 int nRet = PriceUtil.SumPrices(strText, out string strSumPrice, out string strError); if (nRet == -1) { strText = strError; } else { strText = strSumPrice; } } } else { strText = column.DefaultValue; // " "; } } writer.WriteStartElement(j == 0 ? "th" : "td"); if (string.IsNullOrEmpty(column.CssClass) == false) { WriteAttributeString(writer, "class", column.CssClass); } WriteString(writer, strText); writer.WriteEndElement(); // </td> } // strResult.Append("</tr>\r\n"); writer.WriteEndElement(); // </tr> writer.WriteEndElement(); // </tfoot> } writer.WriteEndElement(); // </table> }