高章伟
2022-02-18 8b5f4c6c281cfa548f92de52c8021e37aa81901e
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
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
/**
 * 备品配套の設定
 */
public with sharing class FixtureSetManageController extends CreateRelationListPagingCtrlBase {
    public override Integer getSearchNumMax() {
        //各ページに制御あれば、最大件数を指定する
        // searchNumMax = Integer.valueOf(Label.Product_Select_Limit);
        // searchNumMax = 100;
        pagesize = '100';
        return searchNumMax;
    }
 
    /* 選択されたデータ取得用Soql Fromから*/
    public override String getSelectedDataSql() {
        // オブジェクトAPI名
        selectedDataSql = ' From Fixture_Set_Detail__c';
        selectedDataSql += ' where Fixture_Set__c = \'' + String.escapeSingleQuotes(parentId) + '\'';
        selectedDataSql += ' order by SortInt__c ASC nulls last';
        return selectedDataSql;
    }
 
    // 検索元対象オブジェクトAPI名
    public override String getOriginObjName() {
        // オブジェクトAPI名
        originObjName = 'Product2';
        return originObjName;
    }
    // 検索元対象項目セット
    public override String getOriginObjColumns() {
        // 項目セット
        originObjColumns =  'Id';
        return originObjColumns;
    }
 
    public override String getObjName() {
        // オブジェクトAPI名
        objName = 'Fixture_Set_Detail__c';
        return objName;
    }
    public override String getColumnLeftFieldSetName() {
        // 左の項目セット
        columnLeftFieldSetName = '';
        return columnLeftFieldSetName;
    }
    public override String getColumnRightFieldSetName() {
        // 右の項目セット
        columnRightFieldSetName = 'DetailEdit_RightFieldSet';
        return columnRightFieldSetName;
    }
    // Select 里加直接加的項目 List
    public override List<String> getColumnFieldList() {
        // strColumus 里加 field
        return new List<String>{'Id', 'Product2__r.Name', 'Fixture_Set__c', 'Product_Status_Flag__c'};
    }
    // getObjName 连 getOriginObjName 的 FK
    public override String getFKColumnField() {
        return 'Product2__c';
    }
 
    public override String getRecordTypeId() {
        //ページレイアウトを収得するのレコードタイプ
        recordTypeId = '';
        return recordTypeId;
    }
 
    // ページコントローラに検索処理は、WhereSoql作成のみ、パラメータとして、コンポーネントに渡される
    public override String getSqlWhereStr() {
        sqlWhereStr = '';
 
        if(getIsNeedRunSearch()){
            sqlWhereStr = this.makeSoql(family, category2, category3, category4, category5, assetModelNo, multiStatus);
        }
        system.debug('=========getSqlWhereStr:'+sqlWhereStr);
        return sqlWhereStr;
 
    }
 
    public override Boolean getIsNeedRunSearch() {
        return true;
        //if (String.isBlank(family) && String.isBlank(category2)
        //        && String.isBlank(category3) && String.isBlank(category4)
        //            && String.isBlank(category5) && String.isBlank(assetModelNo)
        //                && String.isBlank(multiStatus)) {
        //    isNeedRunSearch = false;
        //}else{
        //    isNeedRunSearch = true;
        //}
        //return isNeedRunSearch;
    }
 
 
    /*****************検索用******************/
    public String family { get; set; }
    public List<SelectOption> familyOpts { get; private set; }
    public String category2 { get; set; }
    public String category3 { get; set; }
    public String category4 { get; set; }
    public String category5 { get; set; }
    public String assetModelNo { get; set; }
    public String multiStatus { get; set; }
    public String saveType { get; set; }
    //VFで$ObjectType.Fixture_Set_Detail__c.updateableで権限を判断する場合,画面表示途中で
    //プロファイルの権限を変更したら保存時のエラーが表示されません
    public Boolean canSave {get; private set;}
    
    /*****************ソート時再検索条件(画面からの入力条件を無視するため)******************/
    private String nameForSort = null;
    private String cate1ForSort = null;
    private String cate2ForSort = null;
    private String cate3ForSort = null;
    private String cate4ForSort = null;
    private String cate5ForSort = null;
    private String statusForSort = null;
    public Fixture_Set__c parentObj { get; private set; }
    
    public FixtureSetManageController() {
        parentId = ApexPages.currentPage().getParameters().get('pt_recid');
        
        //备品配套下的所有明细
        if (!String.isBlank(this.parentId)) {
            List<Fixture_Set__c> parentObjs = [
                    select Id,Name
                      from Fixture_Set__c where Id = :parentId];
            if (parentObjs.size() > 0) {
                parentObj = parentObjs.get(0);
            }
        }
        Schema.DescribeFieldResult f = Product2.Family.getDescribe();
        List<Schema.PicklistEntry> pList = F.getPicklistValues();
        familyOpts = new List<SelectOption>();
        familyOpts.add(new SelectOption('','--无--'));
        for (Schema.PicklistEntry p : pList) {
            if (p.isActive() == true) {
                familyOpts.add(new SelectOption(p.getValue(), p.getLabel()));
            }
        }
 
        this.canSave = Fixture_Set_Detail__c.sObjectType.getDescribe().isUpdateable() && Fixture_Set_Detail__c.sObjectType.getDescribe().isCreateable();
    }
    
    public void init() {
        searchOppSetParam();
        getSqlWhereStr();
        //isNeedSearchFirst = true;
    }
    
    private void searchOppSetParam() {
        cate1ForSort = family;
        cate2ForSort = category2;
        cate3ForSort = category3;
        cate4ForSort = category4;
        cate5ForSort = category5;
        nameForSort = assetModelNo;
        statusForSort = multiStatus;
    }
 
    public PageReference searchOpp() {
        searchOppSetParam();
 
        if(!getIsNeedRunSearch()){
            return null;
        }
        // 選択済みの製品を取得
        myComponentController.getSelectedDataInfo();
 
        getSqlWhereStr();
        // コンポーネントにSoqlを発行して、ページングする
        myComponentController.searchAndPaging();
        return null;
    }
 
    public PageReference save() {
 
        if (!Fixture_Set_Detail__c.sObjectType.getDescribe().isUpdateable() || !Fixture_Set_Detail__c.sObjectType.getDescribe().isCreateable()) {
            ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR, '无法编辑备品配套明细'));
            return null;
        }
 
        List<Id> delIds = new List<String>();
        //20170906 upsert by UniqueKey__c
        List<Fixture_Set_Detail__c> mfUpsert = new List<Fixture_Set_Detail__c>();
        // MainFixture_Cnt使用的積み上げ是非同期的,为了解决入力规则(主体只能有一个)的问题,此时更新分两次进行
        Fixture_Set_Detail__c bodyMfUpsert = null;
 
        Savepoint sp = Database.setSavepoint();
        Set<String> clearUniqueKeySet = new Set<String>();
        try {
            viewList.sort();
            List<WrapperInfo> bodyWrap = new List<WrapperInfo>();
            List<WrapperInfo> optionWrap = new List<WrapperInfo>();
            for (WrapperInfo wprInfo : viewList) {
                if(!wprInfo.check) continue;
                if (((Fixture_Set_Detail__c) wprInfo.sobj).Is_Body__c) {
                    bodyWrap.add(wprInfo);
                } else {
                    optionWrap.add(wprInfo);
                }
            }
            // Is_Body を かならず先頭にする
            bodyWrap.addAll(optionWrap);
            Integer sortInt = 1;
            Boolean isNeedUpdateParent = false;
            for (WrapperInfo wprInfo : bodyWrap) {
                Fixture_Set_Detail__c robj = (Fixture_Set_Detail__c) wprInfo.sobj;
                if (robj.Is_Body__c) {
                    //选配 :主体の場合は、備品Set保存時に自動でFalseをセットする。
                    robj.Is_Optional__c = false;
                    robj.Is_OneToOne__c = false;
                    robj.SortInt__c     = 1;
                    robj.Name           = parentObj.Name + '-' + ('' + sortInt).leftPad(2, '0');
                    //主体备品配套明细型号
                    parentObj.Fixture_Set_Body_Model_No__c = robj.Fixture_Model_No_F__c;
                    isNeedUpdateParent = true;
                } else {
                    sortInt++;
                    robj.SortInt__c = sortInt;
                    robj.Name       = parentObj.Name + '-' + ('' + sortInt).leftPad(2, '0');
                }
            }
 
            for (WrapperInfo wprInfo : viewList) {
                Fixture_Set_Detail__c robj = (Fixture_Set_Detail__c) wprInfo.sobj;
 
                //20170906 upsert by UniqueKey__c
                // 画面上にチェックした
                if (wprInfo.check) {
                    String uniqueKeyStr = parentObj.id + ':' + robj.product2__c;
                    robj.UniqueKey__c = uniqueKeyStr;
                    if (robj.Is_Body__c) {
                        bodyMfUpsert = robj;
                    } else {
                        mfUpsert.add(robj);
                    }
                    if (String.isBlank(robj.Id)
                            && !String.isBlank(uniqueKeyStr)) {
                        // 新規の場合、ここ単純に Id にて判断
                        clearUniqueKeySet.add(uniqueKeyStr);
                    }
                }
 
                // 画面上にチェックなし、且つ以前がチェックされた製品
                if (!wprInfo.check && wprInfo.oldCheck && selectedIdSet.contains(robj.Id)) {
                    // 一覧から削除
                    if (!String.isBlank(robj.Id)) {
                        delIds.add(robj.Id);
                    }
                }
            }
            if(isNeedUpdateParent){
                update parentObj;
            }
            // 削除、権限ない可能性があるので、FixtureUtilに移動
            if (delIds.size() > 0) {
                FixtureUtil.delFixtureSetDetailByIds(parentObj, delIds);
            }
            List<Fixture_Set_Detail__c> allFSDList = new List<Fixture_Set_Detail__c>();
            // Upsert
            if (mfUpsert.size() > 0) { 
                //Test method error on upsert command
                //System.DmlException: Upsert failed. First exception on row 0 with id a2R0k0000000rogEAA; 
                //first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id]
                allFSDList.addAll(mfUpsert);
            }
            if (bodyMfUpsert != null) {
                allFSDList.add(bodyMfUpsert);
            }
            if(allFSDList.size() > 0) {
                // 用batch逻辑更新【产品注册证状态】
                FixtureSetDetailDailyUpdateBatch.updateProductStatusFlag(allFSDList);
                upsert allFSDList UniqueKey__c;
            }
 
        } catch (Exception ex) {
            System.debug(ex.getStackTraceString());
            ApexPages.addMessages(ex);
            Database.rollback(sp);
            // Id をクリア
            for (Fixture_Set_Detail__c robj : mfUpsert) {
                if (clearUniqueKeySet.contains(robj.UniqueKey__c)) {
                    robj.Id = null;
                }
            }
            return null;
        }
        
        if (saveType == '1') {
            searchOpp();
            saveType = '';
            return null;
        } else if (saveType == '2') {
        // ソート時の変更ある
            myComponentController.getSelectedDataInfo();
            getSqlWhereStr();
            myComponentController.sortTable();
            saveType = '';
            return null;
        } else {
            return cancel();
        }
    }
 
    public PageReference cancel() {
        PageReference ret = null;
        if (!String.isBlank(this.parentId)) {
            ret = new PageReference('/' + this.parentId);
        }
        return ret;
    }
    
    private String makeSoql(String cate1, String cate2, String cate3, String cate4,
            String cate5, String assMode, String status) {
        // from product2
        String soql ='';
        soql += 'where IsActive = true';
 
        // Familyはプルダウン
        if (!String.isBlank(cate1)) {
            soql += ' and Family = \'' + String.escapeSingleQuotes(cate1.replaceAll('%', '\\%')) + '\'';
        }
        if (!String.isBlank(cate2)) {
            soql += ' and Category2__c like \'%' + String.escapeSingleQuotes(cate2.replaceAll('%', '\\%')) + '%\'';
        }
        if (!String.isBlank(cate3)) {
            soql += ' and Category3__c like \'%' + String.escapeSingleQuotes(cate3.replaceAll('%', '\\%')) + '%\'';
        }
        if (!String.isBlank(cate4)) {
            soql += ' and Category4__c like \'%' + String.escapeSingleQuotes(cate4.replaceAll('%', '\\%')) + '%\'';
        }
        if (!String.isBlank(cate5)) {
            soql += ' and Category5__c like \'%' + String.escapeSingleQuotes(cate5.replaceAll('%', '\\%')) + '%\'';
        }
        if (!String.isBlank(assMode)) {
            //soql += ' and Asset_Model_No__c like \'%' + String.escapeSingleQuotes(assMode) + '%\'';
            soql += ' and ( ';
            soql += ' Fixture_Model_No_F__c like \'%' + String.escapeSingleQuotes(assMode.replaceAll('%', '\\%')) + '%\'';
            soql += ' OR Name like \'%' + String.escapeSingleQuotes(assMode.replaceAll('%', '\\%')) + '%\'';
            soql += ' OR OT_CODE_no_link__c like \'%' + String.escapeSingleQuotes(assMode.replaceAll('%', '\\%')) + '%\'';
            soql += ' OR MDM_Model_No__c like \'%' + String.escapeSingleQuotes(assMode.replaceAll('%', '\\%')) + '%\'';
            soql += ' ) ';
            //产品名称(文本) Name_No_link__c → Name , OT CODE OT_CODE_no_link__c, MDM製品型番 MDM_Model_No__c
        }
        if (!String.isBlank(status)) {
            soql += ' and (';
            List<String> vals = status.split('_', -1);
            for (Integer i = 0; i < vals.size(); i++) {
                if (i == vals.size() - 1) {
                    soql += ' SFDA_Status__c = \'' + String.escapeSingleQuotes(vals[i]) + '\')';
                } else {
                    soql += ' SFDA_Status__c = \'' + String.escapeSingleQuotes(vals[i]) + '\' or';
                }
            }
        }
 
        system.debug(soql);
        return soql;
    }
 
    // List<Product2>
    public override void setViewList(List<SObject> queryList) {
        viewList = new List<WrapperInfo>();
 
        // 選択済みの明细
        if (selectedData.size() > 0) {
            for (Integer i = 0; i < selectedData.size(); i++) {
                /* not include the selected data num */
                // 501を超えた場合前500のみを出す  
                //if (i == getSearchNumMax()) continue;
                WrapperInfo w = new WrapperInfo(selectedData[i], myComponentController);
                w.lineNo = i;
                w.orderNo = i + 1;
                w.check = true;
                w.oldCheck = true;
                viewList.add(w);
            }
        }
 
        if (queryList.size() == 0) {
            return;
        }
 
        // queryList に 数式項目を取得
        Savepoint sp = Database.setSavepoint();
 
        // 数式項目値を取れるのために、一回Insertする
        List<Fixture_Set_Detail__c> tempList = new List<Fixture_Set_Detail__c>();
        for (Integer i = 0; i < queryList.size(); i++) {
            // 501を超えた場合前500のみを出す
            if (i == getSearchNumMax()) { break; }
            Fixture_Set_Detail__c mf = new Fixture_Set_Detail__c();
            mf.Fixture_Set__c        = parentId;
            mf.Product2__c           = queryList[i].Id;
            mf.Is_Body__c            = false;
            mf.Is_OneToOne__c        = false;
            mf.Quantity__c           = 1;
            mf.Is_Optional__c        = false;
            mf.DataMigration_Flag__c = true;
//            mf.recalculateFormulas();
            tempList.add(mf);
        }
 
        Database.SaveResult[] results = Database.insert(tempList, false);
 
        final String soqlStr = 'Select {0} {1} ';
        String whereStr = ' FROM Fixture_Set_Detail__c WHERE ID in: tempList';
        String soql = String.format(soqlStr, new String[] {myComponentController.strColumus, whereStr});
 
        tempList = Database.query(soql);
        if (queryList.size() != tempList.size()) {
            //error message 検索処理正しくありません、システム管理者に連絡してください。
           Database.SaveResult dmlResult = results[0];
            if (!dmlResult.isSuccess()) {
                System.debug(System.LoggingLevel.ERROR, '第[' + (1) + ']条 insert error:' + dmlResult);
                ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,
                '第[' + (1) + ']条 insert error:' + dmlResult));
                // 1件目だけlogに出す
            }
            ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,
                    System.Label.CreateRelationListSearchError));
            return;
        }
        // 強制ロールバック
        Database.rollback(sp);
        Map<String, SObject> fsDMap = new Map<String,SObject>();
        for(Fixture_Set_Detail__c fsd : tempList){
            Fixture_Set_Detail__c robj = fsd.clone(false);
            robj.DataMigration_Flag__c = false;
            fsDMap.put(fsd.Product2__c, robj);
        }
 
        Integer addedNum = 0;
        for (Integer i = 0; i < queryList.size(); i++) {
 
            addedNum ++;
            // 501を超えた場合前500のみを出す
            if (addedNum == getSearchNumMax()) { break; }
            SObject mf = fsDMap.get(queryList[i].Id);
            viewList.add(new WrapperInfo(mf, myComponentController));
            viewList[viewList.size() - 1].lineNo = viewList.size() - 1;
        }
 
system.debug('●●●●● setViewList END ' );
    }
}