王 垚
2022-09-05 226dd2b152c0fb06b3f8108ac7740216a8a453c6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
using System.ComponentModel;
using Kingdee.BOS;
using Kingdee.BOS.Core;
using Kingdee.BOS.ServiceHelper;
using System.Data;
 
using Newtonsoft.Json.Linq;
using System;
using Kingdee.BOS.Util;
using System.Linq;
using ZD.Cloud.WebApi;
using Demo.Model.Model.PODemandPlan;
 
using System.Collections.Generic;
using ZD.Share.Common;
using Demo.BillView.PRD;
 
namespace Demo.TimedTaskPlugIn.PRD
{
    [Description("要料计划")]
    [HotUpdate]
    public class TLPlanTimeTaskYl : Kingdee.BOS.Contracts.IScheduleService
    {
 
        public Context Context;
        public void Run(Context ctx, Schedule schedule)
        {
            try
            {
                LogService.Write("提料计划测试");
                Context = ctx;
                string sql = "/*dialect*/  select  FID,FDAYPLANID from sc_TLPLANZXJH where FISZX = 1";
                List<string> sqlList = new List<string>();
                DataTable dt = DBServiceHelper.ExecuteDataSet(Context, sql).Tables[0];
                if (dt.Rows.Count > 0)
                {
                    Extraction();
                    sqlList.Add($"/*dialect*/  update sc_TLPLANZXJH set  FZXDATE = getdate(), FISZX = 2 where FISZX = 1 ");
                    DBServiceHelper.ExecuteBatch(Context, sqlList);
                }
            }
            catch (System.Exception ex)
            {
                //LogHelper.Error(ex.Message.ToString());
            }
        }
 
        public void Extraction()
        {
            try
            {
                LogService.Write("提料计划测试开始");
                //Stopwatch sw = new Stopwatch();
                //sw.Start();//开始计时
                //提料计划预处理 清理提料计划单数据 更新采购订单提料计划数量
                string sql = string.Format(@"
  /*dialect*/
 exec [要料计划预处理] 
 ");
                DBServiceHelper.Execute(Context, sql);
                ////LogService.Write("[提料计划准备阶段]提料计划预处理sql:" + sql);
                //采购订单数据
                sql = @"
 /*dialect*/
select t1.FID,t1.FBillNo,t2.FENTRYID,t2.FWorkShopID as FSUPPLIERID,t3.FNUMBER,t2.FMATERIALID,(tq.FNoStockInQty-t2.FPODemandPlanCount)FQTY
,t1.FPrdOrgId FStockOrgId,t5.FNUMBER FORGNumber,t2.FXQD,t1.FCREATORID,t8.FName ,t1.FDate,'' as F_QIMB_NOTE,'' as FNOTE,0 as FFIXLEADTIME
from T_PRD_MO t1
join T_PRD_MOEntry t2 on t1.FID = t2.FID
join T_PRD_MOENTRY_Q tq on t2.FENTRYID = tq.FENTRYID
join T_BD_DEPARTMENT t3 on t2.FWorkShopID = t3.FDEPTID
join T_ORG_Organizations t5 on t1.FPrdOrgId = t5.FORGID
join T_SEC_user t8 on t1.FCREATORID = t8.FuserId
where tq.FNoStockInQty-t2.FPODemandPlanCount>0
and  t2.FXQD in 
(select distinct FHSeOrderBillNo from Sc_WorkBillSortBillMain)
";
                List<PurchaseInventory> PurchaseInventory = DBServiceHelper.ExecuteDataSet(Context, sql).ToModelList<PurchaseInventory>();
                ////LogService.Write("[提料计划准备阶段]可用采购订单数据sql:" + sql);
                sql = string.Format(@"
 /*dialect*/
SELECT T1.FID,FHMASTERDATE,T1.FENTRYID,t2.FHSeOrderBillNo as FXQD,T1.FBILLNO, FNEEDQTY,0 as FFIXLEADTIME
,FMAXPOQTY,0 as  FMINPOQTY,0 as FJITMATERIALGROUP,0 as FJITMATERIELDEMAND,0 as FJITSAFESTOCK,T1.FMATERIALID,T6.FNUMBER,NEEDQTY, FSTOCKORGID ,FERPCLSID
FROM   (
SELECT FHICMOINTERID FID,FHICMOENTRYID FENTRYID,FPLANDATE FHMASTERDATE,FLACKCOUNT NEEDQTY,FHMATERID FMATERIALID,FHSTOCKORGID FSTOCKORGID,FPRDBILLNO FBILLNO,FSUMPLANCOUNT FNEEDQTY FROM JIT_MOMATERREADYSBILL A
RIGHT JOIN (SELECT MAX(FID)FID FROM JIT_MOMATERREADYSBILL GROUP BY FHICMOENTRYID,FHMATERID) B ON A.FID = B.FID
)T1
JOIN Sc_WorkBillSortBillMain T2 ON T1.FID = T2.FID
JOIN T_BD_MATERIAL T6 ON T1.FMATERIALID = T6.FMATERIALID
JOIN T_BD_MATERIALBASE T4 ON T1.FMATERIALID = T4.FMATERIALID
JOIN T_BD_MATERIALPLAN T5 ON T1.FMATERIALID = T5.FMATERIALID
where FERPCLSID IN ('2') 
AND T1.NEEDQTY>0
AND T1.FENTRYID NOT IN (SELECT DISTINCT FHSOURCEENTRYID FROM t_Prd_ProductPlanEntry)
ORDER BY FHMASTERDATE
");
                ////LogService.Write("[提料计划准备阶段]需要提料数据sql:" + sql);
                DataSet ds = DBServiceHelper.ExecuteDataSet(Context, sql);
                List<DayPlanPpbom> DayPlanPpbom = ds.ToModelList<DayPlanPpbom>();
                //物料+库存组织分类
                var MaterialIDList = DayPlanPpbom.GroupBy(p => new { p.FMATERIALID, p.FStockOrgId }).Select(x => new PODemandPlanTemp { FMATERIALID = x.Key.FMATERIALID, FStockOrgId = x.Key.FStockOrgId }).ToList();
                var _MaterialIDList = MaterialIDList.Where(p => p.FMATERIALID == "163165").ToList();
                ////LogService.Write("[提料计划准备阶段]总物料行数" + MaterialIDList.Count);
                //提料计划数据集临时存储集合
                List<PODemandPlanTemp> PODemandPlanTemp = new List<PODemandPlanTemp>();
                //sql集合 更新采购订单占用的提料计划数量
                List<string> sqlList = new List<string>();
                //MaterialIDList = new List<string> { "105773" };
                foreach (var item in MaterialIDList)
                {
                    //当前物料没有采购订单时 直接跳出
                    List<PurchaseInventory> _PurchaseInventory = PurchaseInventory.Where(x => x.FMATERIALID == item.FMATERIALID && x.FStockOrgId == item.FStockOrgId && x.FQTY > 0).OrderBy(x => x.FENTRYID).ToList();
                    if (_PurchaseInventory.Count == 0)
                    {
                        LogService.Write($"物料:{ item.FMATERIALID},需求单号:{item.FXQD},生产订单号:{item.FBILLNO},日计划工单FID:{item.FID}...未找到对应生产订单信息");
                        continue;
                    }
                    ////LogService.Write(item.FMATERIALID.ToString());
                    //当前物料和库存组织对应的需进行提料计划的数据    
                    List<DayPlanPpbom> _DayPlanPpbom = DayPlanPpbom.Where(x => x.FMATERIALID == item.FMATERIALID && x.FStockOrgId == item.FStockOrgId).ToList();
                    //decimal FMINPOQTY = _DayPlanPpbom.FirstOrDefault().FMINPOQTY;//最小起订量
                    //double FFIXLEADTIME = _DayPlanPpbom.FirstOrDefault().FFIXLEADTIME;//提前期
                    //string FJITmaterialGroup = _DayPlanPpbom.FirstOrDefault().FJITmaterialGroup;//jit物料分类
                    //string FJITMaterielDemand = _DayPlanPpbom.FirstOrDefault().FJITMaterielDemand; //JIT物料需求供货周期
                    //string FJITSafeStock = _DayPlanPpbom.FirstOrDefault().FJITSafeStock; //JIT安全库存
                    decimal NeedQty = 0;
                    //DateTime DATE = _DayPlanPpbom.FirstOrDefault().FHMASTERDATE;//第一个订货起始日期
                    //记录在最小采购量需求下的日计划明细FentyrID
                    List<int> FEntryIdList = new List<int>();
                    foreach (var _item in _DayPlanPpbom)
                    {
                        var PurchaseInventory_scdd = _PurchaseInventory.Where(x => x.FQTY > 0 && x.FXQD == _item.FXQD).OrderBy(x => x.FENTRYID).ToList();
                        if (PurchaseInventory_scdd.Count == 0)
                        {
                            LogService.Write($"物料:{ _item.FMATERIALID},需求单号:{item.FXQD},生产订单号:{_item.FBILLNO},日计划工单FID:{_item.FID}...生产订单数量已被占用完");
                            break;
                        }
                        FEntryIdList.Add(_item.FENTRYID);
                        NeedQty += _item.NeedQty;
                        //增加一个销售订单号匹配的逻辑 优先循环
                        if (PurchaseInventory_scdd.Count > 0)
                        {
                            foreach (var Purchase in PurchaseInventory_scdd)
                            {
                                double _FFIXLEADTIME = Purchase.FFIXLEADTIME;//提前期
                                DateTime _DATE = Convert.ToDateTime(_item.FHMASTERDATE).AddDays(-_FFIXLEADTIME);
                                ////LogService.Write("采购订单号测试:" + Purchase.FBillNo);
                                ////LogService.Write("物料:" + Purchase.FMATERIALID + ",采购订单数量:" + Purchase.FQTY);
                                if (Purchase.FQTY >= NeedQty)
                                {
                                    foreach (int id in FEntryIdList)
                                    {
                                        var DayPlanPpbomls = DayPlanPpbom.Where(c => c.FENTRYID == id && c.FMATERIALID == _item.FMATERIALID).FirstOrDefault();
                                        PODemandPlanTemp.Add(new Demo.Model.Model.PODemandPlan.PODemandPlanTemp
                                        {
                                            FID = DayPlanPpbomls.FID,
                                            FHMASTERDATE = _DATE,
                                            FQty = DayPlanPpbomls.NeedQty,
                                            FBILLNO = DayPlanPpbomls.FBILLNO,
                                            FENTRYID = DayPlanPpbomls.FENTRYID,
                                            FMATERIALID = DayPlanPpbomls.FMATERIALID,
                                            FNumber = DayPlanPpbomls.FNumber,
                                            OLDDATE = DayPlanPpbomls.FHMASTERDATE,
                                            FFIXLEADTIME = _FFIXLEADTIME,
                                            FErpClsID = DayPlanPpbomls.FErpClsID,
 
                                            PurchseFID = Purchase.FID,
                                            PurchseFentryID = Purchase.FENTRYID,
                                            FSUPPLIERID = Purchase.FSUPPLIERID,
                                            PurchseFNUMBER = Purchase.FNUMBER,
                                            PurchseFBillNo = Purchase.FBillNo,
                                            PurchseFqty = Purchase.FQTY,
                                            FStockOrgId = Purchase.FStockOrgId, //采购组织
                                            FORGNumber = Purchase.FORGNumber,
 
                                            FXQD = Purchase.FXQD,
                                            FCREATORID = Purchase.FCREATORID,
                                            FName = Purchase.FName,
                                            FDate = Purchase.FDate,
                                            //FDeliveryDate = Purchase.FDeliveryDate,
                                            F_QIMB_NOTE = Purchase.F_QIMB_NOTE,
                                            FNOTE = Purchase.FNOTE
                                        });
                                        //扣除日计划明细已被分配的数量
                                        DayPlanPpbomls.NeedQty = 0;
                                    }
                                    FEntryIdList.Clear();
                                    //更新采购订单
                                    sqlList.Add($"/*dialect*/ update T_PRD_MOEntry set FPODemandPlanCount  =isnull(FPODemandPlanCount,0)+  '{NeedQty}' where FENTRYID = {Purchase.FENTRYID}");
                                    //扣除当前行对应采购订单数量
                                    var ls = PurchaseInventory.Where(c => c.FENTRYID == Purchase.FENTRYID).FirstOrDefault();
                                    ls.FQTY -= NeedQty;
                                    break;
                                }
                                else
                                {
                                    //更新总需求数量
                                    NeedQty = NeedQty - Purchase.FQTY;
                                    //采购订单数量
                                    decimal _NeedQty = Purchase.FQTY;
                                    List<int> mmm = new List<int>();
                                    foreach (int id in FEntryIdList)
                                    {
                                        var DayPlanPpbomls = DayPlanPpbom.Where(c => c.FENTRYID == id && c.FMATERIALID == _item.FMATERIALID).FirstOrDefault();
                                        decimal Qty = DayPlanPpbomls.NeedQty;//订单数量
                                                                             //if (Qty == 0)
                                                                             //    //LogService.Write("订单数量为0");
                                        if (Qty > _NeedQty)
                                            Qty = _NeedQty; //订单数量>采购订单数量 取采购订单
 
                                        //if (_NeedQty == 0)
                                        //    //LogService.Write("订单数量为0");
 
                                        _NeedQty = _NeedQty - Qty;
                                        PODemandPlanTemp.Add(new Demo.Model.Model.PODemandPlan.PODemandPlanTemp
                                        {
                                            FID = DayPlanPpbomls.FID,
                                            FHMASTERDATE = _DATE,
                                            FQty = Qty,
                                            FBILLNO = DayPlanPpbomls.FBILLNO,
                                            FENTRYID = DayPlanPpbomls.FENTRYID,
                                            FMATERIALID = DayPlanPpbomls.FMATERIALID,
                                            FNumber = DayPlanPpbomls.FNumber,
                                            OLDDATE = DayPlanPpbomls.FHMASTERDATE,
                                            FFIXLEADTIME = _FFIXLEADTIME,
                                            FErpClsID = DayPlanPpbomls.FErpClsID,
 
                                            PurchseFID = Purchase.FID,
                                            PurchseFentryID = Purchase.FENTRYID,
                                            FSUPPLIERID = Purchase.FSUPPLIERID,
                                            PurchseFNUMBER = Purchase.FNUMBER,
                                            PurchseFBillNo = Purchase.FBillNo,
                                            PurchseFqty = Purchase.FQTY,
                                            FStockOrgId = Purchase.FStockOrgId, //采购组织
                                            FORGNumber = Purchase.FORGNumber,
 
                                            FXQD = Purchase.FXQD,
                                            FCREATORID = Purchase.FCREATORID,
                                            FName = Purchase.FName,
                                            FDate = Purchase.FDate,
                                            //FDeliveryDate = Purchase.FDeliveryDate,
                                            F_QIMB_NOTE = Purchase.F_QIMB_NOTE,
                                            FNOTE = Purchase.FNOTE
                                        });
                                        //更新计划数量(剩余需要排的) 继续去计算下一个采购订单
                                        DayPlanPpbomls.NeedQty -= Qty;
                                        //更新采购订单
                                        sqlList.Add($"/*dialect*/ update T_PRD_MOEntry set FPODemandPlanCount = isnull(FPODemandPlanCount,0)+ '{Qty}' where FENTRYID = {Purchase.FENTRYID}");
                                        //更新Model
                                        var ls = PurchaseInventory.Where(c => c.FENTRYID == Purchase.FENTRYID).FirstOrDefault();
                                        ls.FQTY -= Qty;
                                        if (_NeedQty <= 0)
                                        {
                                            foreach (var mm in mmm)
                                            {
                                                FEntryIdList.Remove(mm);
                                            }
                                            break;
                                        }
                                        mmm.Add(id);
                                    }
                                }
                            }
                        }
                        //if (NeedQty > 0)
                        //{
                        //    LogService.Write("[要料计划]生产订单号:" + item.FBILLNO + ",当前物料:" + item.FMATERIALID + ",需求数量:" + _item.NeedQty + " ,占用采购订单后数量剩余:" + NeedQty);
                        //}
                        NeedQty = 0;
                    }
                }
                var PODemandPlanList222 = PODemandPlanTemp.GroupBy(p => new PODemandPlanTemp { PurchseFNUMBER = p.PurchseFNUMBER, FHMASTERDATE = p.FHMASTERDATE }).Select(x => new PODemandPlanTemp { PurchseFNUMBER = x.Key.PurchseFNUMBER, FHMASTERDATE = x.Key.FHMASTERDATE }).ToList();
                var PODemandPlanList = PODemandPlanTemp.GroupBy(p => new { p.PurchseFNUMBER, p.FHMASTERDATE }).Select(x => new PODemandPlanTemp { PurchseFNUMBER = x.Key.PurchseFNUMBER, FHMASTERDATE = x.Key.FHMASTERDATE }).ToList();
                LogService.Write($"提料计划,数据准备完成,保存到Model实体,总行数:{PODemandPlanTemp.Count}");
                int tlmmm = 1;
                JArray FinalyResult = new JArray();
                foreach (var item in PODemandPlanList)
                {
                    DateTime date = item.FHMASTERDATE;
                    string PurchseFNUMBER = item.PurchseFNUMBER;
                    JObject model = new JObject();
                    model.Add("FHDate", date);
                    model.Add("FSettleCurrId", new JObject() { ["Fnumber"] = "PRE001" });
                    model.Add("FSupplierID", new JObject() { ["Fnumber"] = PurchseFNUMBER });
 
                    JArray Fentity = new JArray();
                    List<PODemandPlanTemp> _PODemandPlanList = PODemandPlanTemp.Where(x => x.FHMASTERDATE == date && x.PurchseFNUMBER == PurchseFNUMBER).ToList();
                    foreach (var _item in _PODemandPlanList)
                    {
                        if (!model.ToString().Contains("FHPURCHASEORGID"))
                            model.Add("FHPURCHASEORGID", new JObject() { ["Fnumber"] = _item.FORGNumber });
                        JObject FentityModel = new JObject();
                        FentityModel.Add("FHMaterID", new JObject() { ["Fnumber"] = _item.FNumber });//物料
                        FentityModel.Add("FHQty", _item.FQty);//数量
                        FentityModel.Add("FHSourceInterID", _item.FID);//日计划工单FID
                        FentityModel.Add("FHSourceEntryID", _item.FENTRYID);//日计划工单FENTRYID
                        FentityModel.Add("FHSourceBillNo", _item.FBILLNO);//日计划工单单号
                        FentityModel.Add("FHSourceBillType", "");//日计划工单类型
                        FentityModel.Add("FDayPlanDate", _item.OLDDATE);//日计划工单类型
                        FentityModel.Add("FHRelationQty", _item.PurchseFqty);//关联数量
                        FentityModel.Add("FFIXLEADTIME", _item.FFIXLEADTIME);//提前期
                        FentityModel.Add("FPURCHASEORGID", new JObject() { ["Fnumber"] = _item.FORGNumber });//采购组织
                        FentityModel.Add("FHPOOrderInterID", _item.PurchseFID);// 采购订单内码:FHPOOrderInterID
                        FentityModel.Add("FHPOOrderEntryID", _item.PurchseFentryID); //采购订单子内码:FHPOOrderEntryID
                        FentityModel.Add("FHPOOrderBillNo", _item.PurchseFBillNo); //采购订单号:FHPOOrderBillNo
                        FentityModel.Add("FERPCLSID", _item.FErpClsID); //发料方式
                        FentityModel.Add("FUnitID", new JObject() { ["Fnumber"] = "Pcs" }); //发料方式
 
                        FentityModel.Add("FSalOrderNo", _item.FXQD); //需求单号
                        FentityModel.Add("FCgddCreaterId", new JObject() { ["FUserID"] = _item.FCREATORID }); //采购员
                        FentityModel.Add("FCgDate", _item.FDate); //采购订单单据日期
                        //FentityModel.Add("FCgDeliveryDate", _item.FDeliveryDate); //采购订单交货日期
                        FentityModel.Add("F_QIMB_NOTE", _item.F_QIMB_NOTE); //采购订单摘要
                        FentityModel.Add("FNOTE", _item.FNOTE); //采购订单表体备注
 
                        Fentity.Add(FentityModel);
                    }
                    model.Add("FEntity", Fentity);
                    FinalyResult.Add(model);
                    if ((tlmmm >= 20 || tlmmm == PODemandPlanList.Count) && (tlmmm % 20 == 0 || tlmmm == PODemandPlanList.Count))
                    {
                        //LogService.Write("提料计划新增批量执行,记录循环的当前条数" + tlmmm);
                        JObject jsonRoot = new JObject()
                        {
                            ["Creator"] = "",
                            ["NeedUpDateFields"] = new JArray(),
                            ["NeedReturnFields"] = new JArray(),
                            ["IsDeleteEntry"] = "false",
                            ["SubSystemId"] = "",
                            ["IsVerifyBaseDataField"] = "false",
                            ["Model"] = FinalyResult
                        };
                        CloudClient cloudClient = new CloudClient("http://localhost//k3cloud/");
                        //LogService.Write("提料计划批量执行json:" + jsonRoot.ToString());
                        var result = cloudClient.BatchSave("bsv_ProductPlan", jsonRoot.ToString());
                        JObject saveObj = JObject.Parse(result);
                        string saveIsSuc = saveObj["Result"]["ResponseStatus"]["IsSuccess"].ToString().ToUpper();
                        if (saveIsSuc != "TRUE")
                        {
                            LogService.Write("api错误:" + saveObj);
                        }
                        FinalyResult = new JArray();
                    }
                    tlmmm++;
                }
                //sw.Stop();//结束计时
                ////LogService.Write("提料计划执行完成,运行总时长:" + sw.Elapsed);
                DBServiceHelper.ExecuteBatch(Context, sqlList);
            }
            catch (Exception ex)
            {
                LogService.Write("提料计划跳出:" + ex.Message.ToString());
            }
          
            // var PODemandPlanList22 = PODemandPlanTemp.GroupBy(p => new   {p.FSUPPLIERID,     p.FHMASTERDATE }).ToList();
        }
    }
}