首页 > 编程语言 >C#TMS系统学习(联表报表)

C#TMS系统学习(联表报表)

时间:2024-05-14 14:30:43浏览次数:20  
标签:费用 TMS && C# list 明细 联表 var input

C#TMS系统代码-联表报表学习

领导被裁了之后很快就有人上任了,几乎是无缝衔接,很难让我不想到这早就决定好了。我的职责没有任何变化。感受下来这个系统封装程度很高,我只要会调用方法就行。这个系统交付之后不会有太多问题,更多应该是做小需求,有大的开发任务应该也是第二期的事,嗯?怎么感觉我变成运维了?而且为啥没有技术主管来把把关呢?做好了之后我就直接接手了

还有另外一个PLM系统还没有开发好,只能先着手这个了,不然天天看上去没事做

whatcanisay

费用结算查询-客户汇总

统计客户发货单/寄递单 产生的费用

之前没怎么使用过mysql中的pivot,所以对这里的ToPivotTable()不清楚,花些时间了解一下挺好

//获取报表为啥这里是Post,我只能猜测因为参数太多然后不想把参数放在url上面?
[HttpPost("GetCustomerReport")]
//这个控制器或动作方法不需要身份验证或授权
[AllowAnonymous]
//省略日志记录
[IgnoreLog]
//[FromBody]-请求正文,看来参数真的很多了
public async Task<dynamic> GetCustomerReport([FromBody] TmsBusiCustomerReportListQueryInput input)
{
    //获取数据权限
    //50733 id为表的主键
    //整个系统都是用这个id直接去查,为什么不搞一个枚举类呢?
    var authorizeWhere = new List<IConditionalModel>();
    authorizeWhere = await _userManager.GetConditionAsync<TmsBusiCustomerReportOutput>("50733", "it.F_Id");
    //获取登录人CompanyCode
    var loginUserCompany = new List<string>();
    if (!_userManager.IsAdministrator)
    {
        loginUserCompany = await _repository.Context.Queryable<TmsBaseCompanyEmployeeEntity>().Where(x => x.DeleteMark == null && x.EnabledMark == 1 && x.UserId == _userManager.UserId).GroupBy(x => x.CompanyCode).Select(x => x.CompanyCode).ToListAsync();
    }
    //获取字典项费用类型为一般费用的id
    var dictionarydata = await _repository.Context.Queryable<DictionaryDataEntity>().Where(it => it.DictionaryTypeId == "5183653" && it.DeleteMark == null && it.EnabledMark == 1 && it.FullName == "一般费用").Select(it => it.Id).FirstAsync();
    //获取费用明细
    var CostCheckDetailData = GetData();
    //开查
    //TmsBaseExpenseEntity => 费用类型(跟 费用明细 的 费用类型 不是同一个)
    var data = _db.Queryable<TmsBaseExpenseEntity>()
        //左连接 费用类型=>a 费用明细=>d 条件:费用类型Code = 费用明细的费用代码 
        .LeftJoin(CostCheckDetailData, (a, d) => a.Code == d.F_ExpenseCode)
        //内连接 费用单=>it(费用单与费用明细为主子关系) 条件:费用单Id = 费用明细主表Id
        //连一个加一个,不过取名...我也不好说...叫我来取我估计我直接abcdef按顺序来了
        .InnerJoin<TmsBusiCostCheckEntity>((a, d, it) => it.Id == d.F_CostId)
        //左连接 寄递单=>b 条件:寄递单单号 = 费用单的来源单号
        .LeftJoin<TmsBusiMailingDeliveryEntity>((a, d, it, b) => b.No == it.SourceNo)
        //左连接 付款明细=>e 条件:费用单单号 = 付款明细的取货单号(数据字典里这样写的,应该叫来源单号吧?费用怎么取货呢?)
        .LeftJoin<TmsBuisPaymentDetailEntity>((a, d, it, b, e) => it.No == e.PickupNo)
        //左连接 付款单=>f(付款单与付款明细为主子表关系) 条件:付款单Id = 付款明细主表Id
        .LeftJoin<TmsBusiPaymentEntity>((a, d, it, b, e, f) => e.PaymentId == f.Id)
        //左连接 取货单=>j 条件:取货单单号 = 费用单的来源单号
        .LeftJoin<TmsBusiPickupEntity>((a, d, it, b, e, f, j) => it.SourceNo == j.No)
        //费用单状态
        .Where((a, d, it, b, e, f, j) => it.Status == 2)
        //加上数据权限
        .Where(authorizeWhere)
        //删除是修改删除标记来实现,所以这里要查 非删除单据
        .Where((a, d, it, b, e, f, j) => a.DeleteMark == null && d.F_DeleteMark == null && it.DeleteMark == null && b.DeleteMark == null && e.DeleteMark == null && f.DeleteMark == null && j.DeleteMark == null)
        //费用明细 的 费用类型 = 一般费用 (费用明细里面的 费用类型 跟 费用代码 没有任何关系)
        .Where((a, d, it, b, e, f, j) => d.F_ExpenseType == dictionarydata)
        //管理员查看全部,其他看本公司数据
        .WhereIF(!_userManager.IsAdministrator, (a, d, it, b, e, f, j) => loginUserCompany.Contains(it.CompanyNo))
        //groupby一下,报表是按照使用客户来分组的
        .GroupBy((a, d, it, b, e, f, j) => new
        {
          it.CompanyName,
          it.CustomerName,
          f.Currency,
          a.Code,
        })
        //select数据成TmsBusiCustomerReportOutput
        .Select((a, d, it, b, e, f, j) => new TmsBusiCustomerReportOutput
      	{
          companyName = it.CompanyName,
          customerName =SqlFunc.IIF(it.CustomerName.Contains(".,"), SqlFunc.Replace(it.CustomerName, ".,", ".,"), it.CustomerName),
          ......
          netWeight = SqlFunc.AggregateSum(it.SourceNo.Contains("JD") ? b.NetWeight : j.NetWeight),
          code = a.Code,
          amount = Convert.ToDecimal(SqlFunc.AggregateSum(it.Amount))
        })
        //别忘记MergeTable,一般用了select之后就要想起来
        .MergeTable()
        .WhereIF(!string.IsNullOrEmpty(input.companyName), a => a.companyName.Contains(input.companyName))
        //一大堆查询条件
        ......
        .WhereIF(!string.IsNullOrEmpty(input.amountMin) && !string.IsNullOrEmpty(input.amountMax), a => SqlFunc.Between(a.amount, input.amountMin, input.amountMax))
        //Pivot 行转列 直接看接口方法
        //DataTable ToPivotTable<TColumn, TRow, TData>(Func<T, TColumn> columnSelector, Expression<Func<T, TRow>> rowSelector, Func<IEnumerable<T>, TData> dataSelector);
        //三个参数 
        //columnSelector 行转成的扩列
        //rowSelector 保留列
        //dataSelector 数值列(对应扩列的数据,所以sum)
        //个人理解就是把 code的值变成列了,例子随便写的
        /*
        	之前是 
        	companyName  customerName    code       discountAmount 
            公司01        客户01          费用code01   1
            公司01        客户01          费用code02   1
            公司01        客户01          费用code03   1
            
            变成了
            companyName  customerName  费用code01  费用code02  费用code03
            公司01        客户01         1          1          1   
			
			这里的1是sum(discountAmount),因为这里只有一条
        */
        .ToPivotTable(it => it.code, it => new
        {
            it.companyName,
            it.customerName,
            ......
            it.amount
         }, it => it.Sum(x => x.discountAmount)
         );

    //排除结算币种为空
    DataRow[] foundRow;
    foundRow = data.Select("currency=''");
    foreach (var item in foundRow)
    {
        data.Rows.Remove(item);
    }
    //保存一下
    data.AcceptChanges();
    //下面都是分页操作 List放数据,totalCount总条数
    var list = new List<Dictionary<string, object?>>();
    var totalCount = 0;
    //数据放进List
    foreach (DataRow dr in data.Rows)
    {
        var result = new Dictionary<string, object?>();
        foreach (DataColumn dc in data.Columns)
        {
            result.Add(dc.ColumnName, dr[dc]);
        }
        totalCount++;
        list.Add(result);
    }
	//排序
    if (!string.IsNullOrEmpty(input.sidx))
    {
        switch (input.sidx)
        {
            case "companyName":
            case "customerCode":
            case "customerName":
            case "currency":
                if (input.sort == "desc")
                    list = list.OrderByDescending(x => x[input.sidx]?.ToString()).ToList();
                else
                    list = list.OrderBy(x => x[input.sidx]?.ToString()).ToList();
                break;
            default:
                if (input.sort == "desc")
                    list = list.OrderByDescending(x => x[input.sidx].ObjToDecimal()).ToList();
                else
                    list = list.OrderBy(x => x[input.sidx].ObjToDecimal()).ToList();
                break;
        }
    }
    //获取当页内容放入list
    list = list.Skip(input.pageSize * (input.currentPage - 1)).Take(input.pageSize).ToList();
	//组装数据返回前台
    return new { pagination = new { pageIndex = input.currentPage, input.pageSize, total = totalCount }, list = list };
}

标签:费用,TMS,&&,C#,list,明细,联表,var,input
From: https://www.cnblogs.com/fanwenkeer/p/18191232

相关文章

  • LMOCSO
    EfficientLarge-ScaleMultiobjectiveOptimizationBasedonaCompetitiveSwarmOptimizer原始的CSO\(\vec{x_w}\)是引导粒子,\(\vec{x_l},\vec{v_l}\)分别是待更新粒子和其更新的速度方向。\(R_0,R_1\)是在[0,1]的均匀随机分布。通过图中的引导线可以知道粒子向更优解......
  • Linux 使用 curl 发送请求
    前言请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i、提示:以下是本篇文章正文内容,下面案例可供参考#get请求json入参curlhttp://xxx.xxx:60512/scrm/chat/msg/selectFullChatListForDay-d'{"key":"215EACF20778586C788FFD9187AB0F72","qrDay":"2023-04-25"}�......
  • scrum冲刺1
    这个作业属于哪个课程<班级的链接>这个作业要求在哪里<作业要求的链接>这个作业的目标<你理解的作业目标具体内容>任务分析任务分析界面设计确定所需知识数据分析具体代码实现测试进行任务分析......
  • [996] Upload a file to an Amazon S3 bucket and obtain the URL of it using Python
    Certainly!TouploadafiletoanAmazonS3bucketusingPython(specificallywiththeboto3library)andobtainthelink(URL)forthatfile,followthesesteps:InstallBoto3:Makesureyouhavetheboto3libraryinstalled.Ifnot,youcaninstallit......
  • Jmeter - BeanSell 后置处理器 结合 HttpClient 使用
    背景:在后置处理器中发送POST请求,请求体为JSON数据疑问:1.如果获取Cookie?2.HttpClient怎么发送POST?3.HttpClient怎么添加Cookie?解决:1.如果获取Cookie?importorg.apache.jmeter.protocol.http.control.CookieManager;importorg.apache.jmeter.protocol.http.control.Coo......
  • Codeforces Round 943 (Div. 3)
    CodeforcesRound943(Div.3)1968D-枚举思路:每个人走的位置最多会形成长度为n的环,所以直接枚举走到某个位置之后后面就不走了的所有情况的最大值,相互比较即可1968E-构造题意:设\(F(A_i,A_j)=|x_i-x_y|+|y_i-y_j|\),在\(N*N\)的矩阵中选n个点使所有不同的\(F(A_i,A_j)=|x_i-......
  • CSR客户端渲染和服务器端渲染(SSR)
    CSR指的是客户端渲染(Client-SideRendering)。在客户端渲染中,整个页面的渲染过程发生在用户的浏览器上,而不是在服务器上。在传统的服务器端渲染(SSR)中,服务器负责将页面的HTML内容完全渲染好,并将其发送给浏览器。但在客户端渲染中,浏览器会下载页面的初始HTML结构,然后使用JavaSc......
  • C#应用的欢迎界面窗体方案 - 开源研究系列文章
          这次整理以前的代码,然后想到了应用的欢迎界面窗体的问题。这个例子是在应用中启动一个线程来进行显示欢迎窗体的,对于应用的启动无影响,与其他人的源码不相同,欢迎读者进行复用此类库。      以前有编写过欢迎界面窗体的代码,不过这次翻出来的时候想把它完善一下......
  • 文件IO完成libjpeg库的移植,并设计程序实现在LCD上的任意位置显示一张任意大小的jpg图
    文件IO:完成libjpeg库的移植,并设计程序实现在LCD上的任意位置显示一张任意大小的jpg图片,注意不要越界。1.库的移植1.下载需要移植的库的源码包,libjpeg库源码包在官网可以下载www.ijg.org2.解压压缩包,解压后找到自述文件README,打开README了解libjpeg库的使用规则!3.打开源码包......
  • CompletableFuture学习
    CompleteFuture学习packagecom.example.CompleteFutureTest;importjava.util.concurrent.CompletableFuture;importjava.util.concurrent.ExecutionException;/***completeFuture用法*/publicclassTest{publicstaticvoidmain(String[]args)throwsI......