/// <inheritdoc /> public override IQueryResult Execute(string expr, IEntitiesSerializer serializer) { var csv = expr; expr = ParsingF.Line(ref csv); var parsed = new CsvParser(ParsingF.Optional(ref expr, "-")); var sb = new StringBuilder(); if (ParsingF.Optional(ref expr, "mark")) { var filt = Regularize(ParsingF.DetailQuery(ref expr)); ParsingF.Optional(ref expr, "as"); var marker = ParsingF.Token(ref expr); ParsingF.Eof(expr); if (string.IsNullOrWhiteSpace(marker)) { throw new FormatException("格式错误"); } parsed.Parse(csv); sb.AppendLine($"{parsed.Items.Count} parsed"); RunMark(filt, parsed, marker, sb); } else if (ParsingF.Optional(ref expr, "unmark")) { var filt = Regularize(ParsingF.DetailQuery(ref expr)); ParsingF.Eof(expr); RunUnmark(filt, sb); } else if (ParsingF.Optional(ref expr, "check")) { var filt = Regularize(ParsingF.DetailQuery(ref expr)); ParsingF.Eof(expr); parsed.Parse(csv); sb.AppendLine($"{parsed.Items.Count} parsed"); RunCheck(filt, parsed, sb); } else { ParsingF.Optional(ref expr, "auto"); var filt = Regularize(ParsingF.DetailQuery(ref expr)); ParsingF.Optional(ref expr, "as"); var marker = ParsingF.Token(ref expr); ParsingF.Eof(expr); if (string.IsNullOrWhiteSpace(marker)) { throw new FormatException("格式错误"); } parsed.Parse(csv); sb.AppendLine($"{parsed.Items.Count} parsed"); var markerFilt = new StmtVoucherDetailQuery( filt.VoucherQuery, new IntersectQueries <IDetailQueryAtom>( filt.DetailEmitFilter.DetailFilter, new StmtDetailQuery(marker))); var nullFilt = new StmtVoucherDetailQuery( filt.VoucherQuery, new IntersectQueries <IDetailQueryAtom>( filt.DetailEmitFilter.DetailFilter, new StmtDetailQuery(""))); var nmFilt = new StmtVoucherDetailQuery( filt.VoucherQuery, new IntersectQueries <IDetailQueryAtom>( filt.DetailEmitFilter.DetailFilter, new UnionQueries <IDetailQueryAtom>( new StmtDetailQuery(""), new StmtDetailQuery(marker)))); RunUnmark(markerFilt, sb); RunMark(nullFilt, parsed, marker, sb); RunCheck(nmFilt, parsed, sb); } return(new PlainText(sb.ToString())); }
private void RunMark(IVoucherDetailQuery filt, CsvParser parsed, string marker, StringBuilder sb) { if (filt.IsDangerous()) { throw new SecurityException("检测到弱检索式"); } var marked = 0; var remarked = 0; var converted = 0; var res = Accountant.SelectVouchers(filt.VoucherQuery).ToList(); foreach (var b in parsed.Items) { bool Trial(bool date) { var resx = date ? res.Where(v => v.Date == b.Date) : res.OrderBy(v => v.Date.HasValue ? Math.Abs((v.Date.Value - b.Date).TotalDays) : double.PositiveInfinity); var voucher = resx .FirstOrDefault(v => v.Details.Any(d // ReSharper disable once PossibleInvalidOperationException => (d.Fund.Value - b.Fund).IsZero() && d.IsMatch(filt.DetailEmitFilter.DetailFilter))); if (voucher == null) { return(false); } var o = voucher.Details.First(d // ReSharper disable once PossibleInvalidOperationException => (d.Fund.Value - b.Fund).IsZero() && d.IsMatch(filt.DetailEmitFilter.DetailFilter)); if (o.Remark == null) { marked++; } else if (o.Remark == marker) { remarked++; } else { converted++; } o.Remark = marker; Accountant.Upsert(voucher); return(true); } if (Trial(true) || Trial(false)) { continue; } sb.AppendLine(b.Raw); } sb.AppendLine($"{marked} marked"); sb.AppendLine($"{remarked} remarked"); sb.AppendLine($"{converted} converted"); }