李彤
2022-09-23 d79fcb2a960e8b0e18fe039d892f98187b08866d
招标项目失单报告
4个文件已修改
17个文件已添加
1508 ■■■■■ 已修改文件
force-app/main/default/aura/TenderLostApp/TenderLostApp.app 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/TenderLostApp/TenderLostApp.app-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/TenderLostApp/TenderLostApp.auradoc 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/TenderLostApp/TenderLostApp.css 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/TenderLostApp/TenderLostApp.svg 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/TenderLostApp/TenderLostAppController.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/TenderLostApp/TenderLostAppHelper.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/TenderLostApp/TenderLostAppRenderer.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CommonUtils.cls 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CommonUtilsTest.cls 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/OpportunityTrigger.cls 407 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/OpportunityTriggerTest.cls 160 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TenderLostController.cls 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TenderLostControllerTest.cls 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TenderResultConfirmTaskBatch.cls 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TenderResultConfirmTaskBatchTest.cls 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/lwc/tenderLost/__tests__/tenderLost.test.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/lwc/tenderLost/tenderLost.html 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/lwc/tenderLost/tenderLost.js 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/lwc/tenderLost/tenderLost.js-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TenderLostPage.page 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/aura/TenderLostApp/TenderLostApp.app
New file
@@ -0,0 +1,3 @@
<aura:application access="public" extends="ltng:outApp">
    <aura:dependency resource="c:TenderLostApp"/>
</aura:application>
force-app/main/default/aura/TenderLostApp/TenderLostApp.app-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<AuraDefinitionBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>55.0</apiVersion>
    <description>A Lightning Application Bundle</description>
</AuraDefinitionBundle>
force-app/main/default/aura/TenderLostApp/TenderLostApp.auradoc
New file
@@ -0,0 +1,6 @@
<aura:documentation>
    <aura:description>Documentation</aura:description>
    <aura:example name="ExampleName" ref="exampleComponentName" label="Label">
        Example Description
    </aura:example>
</aura:documentation>
force-app/main/default/aura/TenderLostApp/TenderLostApp.css
New file
@@ -0,0 +1,2 @@
.THIS {
}
force-app/main/default/aura/TenderLostApp/TenderLostApp.svg
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="120px" height="120px" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <path d="M120,108 C120,114.6 114.6,120 108,120 L12,120 C5.4,120 0,114.6 0,108 L0,12 C0,5.4 5.4,0 12,0 L108,0 C114.6,0 120,5.4 120,12 L120,108 L120,108 Z" id="Shape" fill="#2A739E"/>
        <path d="M77.7383308,20 L61.1640113,20 L44.7300055,63.2000173 L56.0543288,63.2000173 L40,99.623291 L72.7458388,54.5871812 L60.907727,54.5871812 L77.7383308,20 Z" id="Path-1" fill="#FFFFFF"/>
    </g>
</svg>
force-app/main/default/aura/TenderLostApp/TenderLostAppController.js
New file
@@ -0,0 +1,5 @@
({
    myAction : function(component, event, helper) {
    }
})
force-app/main/default/aura/TenderLostApp/TenderLostAppHelper.js
New file
@@ -0,0 +1,5 @@
({
    helperMethod : function() {
    }
})
force-app/main/default/aura/TenderLostApp/TenderLostAppRenderer.js
New file
@@ -0,0 +1,5 @@
({
// Your renderer method overrides go here
})
force-app/main/default/classes/CommonUtils.cls
@@ -28,27 +28,31 @@
     //查询  普通科室
    //  public static string GetPTKS(String content,String ParentId)
    //  {
    //      String paramYy = 'HP';
    //      String sql = 'select ';
    //      String props = GetSqlToPorps(account.SObjectType);
    //      sql += props;
    //      sql += ' from account';
    //      sql += ' where Parent.Parent.RecordType_DeveloperName__c   = :paramYy';
    //      if(content != null && content != '')
    //      {
    //          content = '%'+content+'%';
    //          sql += ' and Name like :content ';
    //      }
    //      if(ParentId != null && ParentId != '')
    //      {
    //          sql += ' and Parentid = :ParentId ';
    //      }
    //      sql += ' limit 5 ';
    //      List<account> arrays = Database.query(sql);
    //      return JSON.serialize(arrays);
    //  }
     public static string GetPTKS(String content, List<String> ParentIds, Boolean checkOwner)
     {
        String paramYy = 'HP';
        String sql = 'select ';
        String props = GetSqlToPorps(account.SObjectType);
        sql += props;
        sql += ' from account';
        sql += ' where Parent.Parent.RecordType_DeveloperName__c   = :paramYy';
        if(content != null && content != '')
        {
            content = '%'+content+'%';
            sql += ' and Name like :content ';
        }
        if(ParentIds != null && ParentIds.size() > 0)
        {
            sql += ' and Parent.Parentid in :ParentIds ';
        }
        if (checkOwner) {
            String userId = UserInfo.getUserId();
            sql += ' and OwnerId = :userId';
        }
        sql += ' limit 5 ';
        List<account> arrays = Database.query(sql);
        return JSON.serialize(arrays);
     }
 
     //查询  普通科室
force-app/main/default/classes/CommonUtilsTest.cls
@@ -56,7 +56,9 @@
        //查询  医院下的科室 包括战略和普通科室
        CommonUtils.GetYYChilders('test',hospital.Id);
         //查询  普通科室
        // CommonUtils.GetPTKS('test',hospital.Id);
        List<String> hospitals = new List<String>();
        hospitals.add(hospital.Id);
        CommonUtils.GetPTKS('test',hospitals,false);
        //查询  普通科室
        // CommonUtils.GetPTKSByYYParent('test',hospital.Id);
        //查询  战略科室
@@ -76,7 +78,8 @@
        //获取选项列表值
        CommonUtils.GetSelectedValues( Tender_information__c.irrelevantReasons__c.getDescribe());
        CommonUtils.getPicklistValues( 'PCLLostBrand__c','ProductClass__c','ProductCategory__c');
        // CommonUtils.getPicklistValues( 'PCLLostBrand__c','ProductClass__c','ProductCategory__c');
        CommonUtils.getPicklistValues( 'Tender_information__c','InfoType__c','subInfoType__c');
    }
force-app/main/default/classes/OpportunityTrigger.cls
@@ -1,5 +1,7 @@
public without sharing class OpportunityTrigger {
    public static Boolean isFirst = true;
    public static void lockOpportunityFile(List<Opportunity> newList, Map<Id, Opportunity> newMap, List<Opportunity> oldList, Map<Id, Opportunity> oldMap) {
        List<String> targetIds = new List<String>();
@@ -20,6 +22,7 @@
        update ofileList;
    }
    //CHAN-AZJ6JS 追溯系统来的询价,取消WIN时,经销商订单自动改到“驳回”
    public static void changeConsumableOrderStatus(List<Opportunity> newList, Map<Id, Opportunity> newMap, List<Opportunity> oldList, Map<Id, Opportunity> oldMap) {
        
@@ -163,10 +166,14 @@
                //     temptender.IsReactionOpp__c = true;
                //     tenderMap.put(temptender.id ,temptender ); 
                // }
                // 合并判断条件
                // 合并判断条件
                //20220803 you 招标项目增加 取消,中标结果更新确认条件
                if((op.SAP_Send_OK__c != oldopp.SAP_Send_OK__c) || 
                    ((op.StageName__c.equals('失单') && !oldopp.StageName__c.equals('失单')) || 
                    (!op.StageName__c.equals('失单') && oldopp.StageName__c.equals('失单')))) {
                    (!op.StageName__c.equals('失单') && oldopp.StageName__c.equals('失单'))) ||
                    ((op.StageName__c.equals('取消') && !oldopp.StageName__c.equals('取消')) ||
                    (!op.StageName__c.equals('取消') && oldopp.StageName__c.equals('取消'))) ||
                    (String.isNotBlank(op.ConfirmationofAward__c) && op.ConfirmationofAward__c!=oldopp.ConfirmationofAward__c)) {
                    for (Tender_Opportunity_Link__c link : links) {
                        if (link.Opportunity__c == op.Id) {
                            Tender_information__c temptender = new Tender_information__c();
@@ -293,5 +300,401 @@
        }
    }
    //LastBuy 预留产品 lt 20220315 end
//SWAG-CHL67J 【委托】【FY23询价改善】-询价页面/招标项目增加统计字段 fy start
// public static void UpdateBidNumber(List<Opportunity> newList, Map<Id, Opportunity> newMap, List<Opportunity> oldList, Map<Id, Opportunity> oldMap){
//     List<Id> OpportunityIdList = new List<Id>();
//     Boolean flag = true;
//     for (Opportunity opp : newList) {
//         OpportunityIdList.add(opp.Id);
//         Opportunity oldopp = oldMap == null? null : oldMap.get(opp.Id);
//         if(oldopp==null){
//             if(opp.NumberOfBids__c!=null||opp.BidWinningNumber__c!=null){
//                 flag = true;
//             }
//         }else{
//             if(opp.NumberOfBids__c!=oldopp.NumberOfBids__c||opp.NumberOfBids__c!=oldopp.NumberOfBids__c){
//                 flag = true;
//             }
//         }
//     }
//     system.debug('newList+++'+newList);
//     system.debug('oldList+++'+oldList);
//     if(flag){
//         List<Tender_Opportunity_Link__c> TenderOpportunityLinkList = [select Tender_information__c from Tender_Opportunity_Link__c where Opportunity__c in:OpportunityIdList];
//         Set<Id> enderOpportunityId = new Set<Id>();
//         if(TenderOpportunityLinkList.size()>0){
//             for (Tender_Opportunity_Link__c TenderOpportunity : TenderOpportunityLinkList) {
//                 enderOpportunityId.add(TenderOpportunity.Tender_information__c);
//             }
//         }
//         system.debug('TenderOpportunityLinkList+++'+TenderOpportunityLinkList);
//         List<Tender_Opportunity_Link__c> TenderOpportunityLinkList2 = [select Tender_information__c,Opportunity__r.NumberOfBids__c,Opportunity__r.BidWinningNumber__c from Tender_Opportunity_Link__c where Tender_information__c in:enderOpportunityId];
//         Map<String,Tender_information__c> TenderinformationMap = new Map<String,Tender_information__c>();
//         system.debug('TenderOpportunityLinkList2+++'+TenderOpportunityLinkList2);
//         if(TenderOpportunityLinkList2.size()>0){
//             for(Tender_Opportunity_Link__c TenderOpportunity2 :TenderOpportunityLinkList2){
//                     if(TenderinformationMap.containsKey(TenderOpportunity2.Tender_information__c)){
//                         Tender_information__c Tender_informationvalue = new Tender_information__c();
//                         Tender_informationvalue = TenderinformationMap.get(TenderOpportunity2.Tender_information__c);
//                         Tender_informationvalue.NumberOfBids__c=Tender_informationvalue.NumberOfBids__c+TenderOpportunity2.Opportunity__r.NumberOfBids__c;
//                         Tender_informationvalue.BidWinningNumber__c=Tender_informationvalue.BidWinningNumber__c+TenderOpportunity2.Opportunity__r.BidWinningNumber__c;
//                         TenderinformationMap.put(TenderOpportunity2.Tender_information__c, Tender_informationvalue);
//                     }else{
//                         Tender_information__c Tender_informationvalue = new Tender_information__c();
//                         Tender_informationvalue.Id=TenderOpportunity2.Tender_information__c;
//                         Tender_informationvalue.NumberOfBids__c=TenderOpportunity2.Opportunity__r.NumberOfBids__c;
//                         Tender_informationvalue.BidWinningNumber__c=TenderOpportunity2.Opportunity__r.BidWinningNumber__c;
//                         TenderinformationMap.put(TenderOpportunity2.Tender_information__c, Tender_informationvalue);
//                     }
//             }
//         }
//         List<Tender_information__c> Tender_informationList = new List<Tender_information__c>();
//         for (Tender_information__c value : TenderinformationMap.values()) {
//             Tender_informationList.add(value);
//         }
//         system.debug('Tender_informationList+++'+Tender_informationList);
//         update Tender_informationList;
//     }
// }
//SWAG-CHL67J 【委托】【FY23询价改善】-询价页面/招标项目增加统计字段 fy end
    //add 询价跟进任务开发 - 3.创建失单任务 sx 20220617 start
    //询价中标结果确认竞争对手中标时实时创建失单任务
    public static void createTaskByOppConfirmationofAward(List<Opportunity> newList, Map<Id, Opportunity> newMap, List<Opportunity> oldList, Map<Id, Opportunity> oldMap){
        if (!isFirst) {
            return;
        }
        Set<Id> oppoIds = new Set<Id>();
        for(Opportunity op : newList){
            Opportunity oldopp =  oldMap.get(op.Id);
            //询价中标结果确认竞争对手中标时实时创建失单任务 且 询价状态1等于询价
            if (oldopp.ConfirmationofAward__c != '竞争对手中标' && op.ConfirmationofAward__c == '竞争对手中标' && op.StageName__c == '询价' && op.LeakageNumber__c !=1){
                oppoIds.add(op.Id);
            }
        }
        if (!oppoIds.isEmpty()) {
            // 有效失单状态一览
            List<String> validStatus = new List<String>{'申请中', '提交', '批准'};
            // 询价失单/取消报告查询
            List<Lost_cancel_report__c> lostCancelReportList = [SELECT Id, Opportunity__c from Lost_cancel_report__c WHERE Opportunity__c in :oppoIds and Report_Status__c in: validStatus];
            //<询价Id, 失单报告>
            Map<String, Lost_cancel_report__c> lostCancelReportMap = new Map<String, Lost_cancel_report__c>();
            for(Lost_cancel_report__c lcr : lostCancelReportList){
                if (!lostCancelReportMap.isEmpty() && lostCancelReportMap.containsKey(lcr.Opportunity__c)) {
                    // no action
                } else {
                    lostCancelReportMap.put(lcr.Opportunity__c, lcr);
                }
            }
            List<Task__c> insTaskList = new List<Task__c>();
            // 定义需要更新的询价任务
            List<Opportunity> updateOpportunity = new List<Opportunity>();
            // 记录类型:失单报告任务
            List<RecordType> recordTypes = [select Id from RecordType where IsActive = true and SobjectType = 'task__c' and DeveloperName = 'LoseListTask'];
            Id loseListTask_TaskId = recordTypes.get(0).Id;
            //String taskName = '';
            for(Opportunity opp : newList) {
                //没有已提交的失单报告
                if(!lostCancelReportMap.containsKey(opp.Id) && oppoIds.contains(opp.Id)) {
                    //创建失单任务提醒
                    Task__c tempTask = new Task__c();
                    tempTask.RecordTypeId = loseListTask_TaskId;
                    tempTask.taskDifferent__c = '被动任务';
                    tempTask.taskStatus__c = '02 接受';       //任务状态2
                    tempTask.assignee__c = opp.OwnerId;    //被分配者
                    tempTask.account__c = opp.AccountId;
                    tempTask.Name = '失单结果确认:' + opp.Opportunity_No__c;
                    tempTask.OwnerId = opp.OwnerId;   //所有人
                    tempTask.OpportunityId__c = opp.Id;
                    tempTask.ConfirmDate__c = Date.today();
                    insTaskList.add(tempTask);
                    //更新询价  Task_createTime__c
                    Opportunity uopp  = new Opportunity();
                    uopp.Id = opp.Id;
                    uopp.LostTask_createTime__c  = Date.today();
                    updateOpportunity.add(uopp);
                }
            }
            if (!insTaskList.isEmpty()) {
                insert insTaskList;
            }
            if (!updateOpportunity.isEmpty()) {
                update updateOpportunity;
            }
        }
        isFirst = false;
    }
    //add 询价跟进任务开发 - 3.创建失单任务 sx 20220617 end
    //询价跟进任务开发
    public static void opportunityTasks(List<Opportunity> newList, Map<Id, Opportunity> newMap, List<Opportunity> oldList, Map<Id, Opportunity> oldMap){
        Set<Id> oppoIds = new Set<Id>();
        for(Opportunity op : newList){
            Opportunity oldopp =  oldMap.get(op.Id);
            //询价中标结果确认竞争对手中标时实时创建失单任务 且 询价状态1等于询价
            if (oldopp.ConfirmationofAward__c != 'OLY中标' && op.ConfirmationofAward__c == 'OLY中标' && op.StageName__c == '询价'){
                oppoIds.add(op.Id);
                //确认中标结果时间 创建任务时间  20220629 sx
                op.ConfirmationofAward_createTime__c = Date.today();
                if(op.Task_createTime__c!=null){
                    //是否按时确认:3个工作日内按时1,不按时0
                    String inttemp = CalendarUtil.getWorkDayNum(String.valueOf(op.Task_createTime__c), String.valueOf(op.ConfirmationofAward_createTime__c));
                    op.Is_ConfirmationofAward__c = Integer.valueOf(inttemp) > 3 ? 0 : 1;
                }
            }
            //20220628会议新需求  对手中标 7.中标日清空
            if(oldopp.ConfirmationofAward__c != '竞争对手中标' && op.ConfirmationofAward__c == '竞争对手中标'){
                op.Closing_Bid_Date__c = null;
                op.ConfirmationofAward_createTime__c = Date.today();
                if(op.Task_createTime__c!=null){
                    //是否按时确认:3个工作日内按时1,不按时0
                    String inttemp = CalendarUtil.getWorkDayNum(String.valueOf(op.Task_createTime__c), String.valueOf(op.ConfirmationofAward_createTime__c));
                    op.Is_ConfirmationofAward__c = Integer.valueOf(inttemp) > 3 ? 0 : 1;
                }
            }
        }
        if(!oppoIds.isEmpty()){
            list<Tender_Opportunity_Link__c> toppLinkList = [Select Id, Opportunity__c, Tender_information__c,Tender_information__r.ResultDate__c FROM Tender_Opportunity_Link__c WHERE Opportunity__c in :oppoIds];
            Map<String, Tender_Opportunity_Link__c> toopLinkMap = new Map<String, Tender_Opportunity_Link__c>();
            for(Tender_Opportunity_Link__c tol : toppLinkList){
                toopLinkMap.put(tol.Opportunity__c, tol);
            }
            for (String key : toopLinkMap.keySet()) {
                Opportunity oppoTemp = newMap.get(key);
                //20220628会议新需求  OLY中标 7.中标日(结果记录日)= 招标项目.结果记录日
                oppoTemp.Closing_Bid_Date__c = toopLinkMap.get(key).Tender_information__r.ResultDate__c;
                System.debug('============'+toopLinkMap.get(key).Tender_information__r.ResultDate__c);
                //是否按时确认:3个工作日内按时1,不按时0
                //String inttemp = CalendarUtil.getWorkDayNum(String.valueOf(oppoTemp.Task_createTime__c), String.valueOf(oppoTemp.ConfirmationofAward_createTime__c));
                //oppoTemp.Is_ConfirmationofAward__c = Integer.valueOf(inttemp) > 3 ? 0 : 1;
            }
        }
        Integer i = 0;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
    }
}
force-app/main/default/classes/OpportunityTriggerTest.cls
@@ -121,7 +121,7 @@
            Body = EncodingUtil.base64Decode('test')
        );
        insert att3;
        delete att3;
        //delete att3;
        
        Rental_Apply__c rentalApply = new Rental_Apply__c();
        // '引当完了' -> 已批准
@@ -139,26 +139,27 @@
        rentalApply.Hope_Lonaer_date_Num__c = 6;
        insert rentalApply;
        
        Attachment att4 = new Attachment(
            Name = 'ORDER-123456.pdf',
            parentId = rentalApply.Id,
            Body = EncodingUtil.base64Decode('test')
        );
        insert att4;
        delete att4;
        // Attachment att4 = new Attachment(
        //     Name = 'ORDER-123456.pdf',
        //     parentId = rentalApply.Id,
        //     Body = EncodingUtil.base64Decode('test')
        // );
        // insert att4;
        // delete att4;
        
        Consumable_order__c co = new Consumable_order__c();
        insert co;
        // Consumable_order__c co = new Consumable_order__c();
        // insert co;
        
        Attachment att5 = new Attachment(
            Name = 'ORDER-123456.pdf',
            parentId = co.Id,
            Body = EncodingUtil.base64Decode('test')
        );
        insert att5;
        // Attachment att5 = new Attachment(
        //     Name = 'ORDER-123456.pdf',
        //     parentId = co.Id,
        //     Body = EncodingUtil.base64Decode('test')
        // );
        // insert att5;
        //delete att5;
        
        System.Test.stopTest();
       // OpportunityTrigger.intI();
    }
}
@@ -322,9 +323,16 @@
        opp1.Authorized_DB_No__c = '123';
        opp1.Contract_DB_SalesDept_complite_day__c = Date.today();
        opp1.NotesApprovedNo__c = '123';
        update opp1;
        LastbuyProduct__c wqe = new LastbuyProduct__c();
        wqe.InquiryCode__c=opp1.Id;
        wqe.LastbuyQuantity__c=1;
        wqe.ActualQuantity__c=1;
        insert wqe;
        opp1.SAP_Send_OK__c = false;
        opp1.Reason_Cancel_WIN__c = '1.终止合同';
        update opp1;
        //lt 注释掉 te1
        // //招标项目
        // Tender_information__c te1 = new Tender_information__c();
@@ -341,18 +349,18 @@
        //新建询价时,赋值招投标项目,打上标识
        Opportunity opp2 = new Opportunity(
            Name = 'test opp1',
            StageName = '引合',
            CurrencyIsoCode = 'USD',
            CloseDate = Date.today(),
            AccountId = depart.Id,
            Closing_Bid_Date__c = Date.today().addDays(-5),
            Hospital__c = company.Id,
            Competitor__c = 'A'
            //,Bidding_Project_Name_Bid__c = te1.Id  //lt 20220316
        );
        insert opp2;
        // Opportunity opp2 = new Opportunity(
        //     Name = 'test opp1',
        //     StageName = '引合',
        //     CurrencyIsoCode = 'USD',
        //     CloseDate = Date.today(),
        //     AccountId = depart.Id,
        //     Closing_Bid_Date__c = Date.today().addDays(-5),
        //     Hospital__c = company.Id
        //     // ,Competitor__c = 'A'
        //     //,Bidding_Project_Name_Bid__c = te1.Id  //lt 20220316
        // );
        // insert opp2;
        System.Test.stopTest();
@@ -389,4 +397,96 @@
  }
  //LastBuy 预留产品 lt 20220315 end
   //add start 20220623
   @isTest
   static void test_createTaskByOppConfirmationofAward() {
    User user = new User(Test_staff__c = true);
        user.LastName = '_サンブリッジ';
        user.FirstName = 'う';
        user.Alias = 'う';
        user.Email = 'olympusTest03@sunbridge.com';
        user.Username = 'olympusTest03@sunbridge.com';
        user.CommunityNickname = 'う';
        user.IsActive = true;
        user.EmailEncodingKey = 'ISO-2022-JP';
        user.TimeZoneSidKey = 'Asia/Tokyo';
        user.LocaleSidKey = 'ja_JP';
        user.LanguageLocaleKey = 'ja';
        user.ProfileId = System.Label.ProfileId_SystemAdmin;
        user.Job_Category__c = '销售推广';
        user.Province__c = '上海市';
        user.Use_Start_Date__c = Date.today().addMonths(-6);
        user.SalesManager__c = UserInfo.getUserId();
        user.BuchangApprovalManagerSales__c = UserInfo.getUserId();
        user.JingliApprovalManager__c = UserInfo.getUserId();
        user.BuchangApprovalManager__c = UserInfo.getUserId();
        user.ZongjianApprovalManager__c = UserInfo.getUserId();
    List<RecordType> rectCo = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '病院'];
        if (rectCo.size() == 0) {
            return;
        }
        List<RecordType> rectSct = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '戦略科室分類 呼吸科'];
        if (rectSct.size() == 0) {
            return;
        }
        List<RecordType> rectDpt = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '診療科 消化科'];
        if (rectDpt.size() == 0) {
            return;
        }
        StaticParameter.EscapeOpportunityBefUpdTrigger = true;
        StaticParameter.EscapeSyncOpportunityTrigger = true;
        StaticParameter.EscapeNFM007Trigger = true;
        StaticParameter.EscapeOpportunityHpDeptUpdTrigger = true;
        StaticParameter.EscapeSyncOpportunityTrigger = true;
        System.runAs(new User(Id = Userinfo.getUserId())) {
            insert user;
        // テストデータ
        Account company = new Account();
        company.RecordTypeId = rectCo[0].Id;
        company.Name         = 'NFM007TestCompany';
        upsert company;
        Account section = new Account();
        section.RecordTypeId = rectSct[0].Id;
        section.Name         = '*';
        section.Department_Class_Label__c = '消化科';
        section.ParentId                  = company.Id;
        section.Hospital_Department_Class__c = company.Id;
        upsert section;
        Account depart = new Account();
        depart.RecordTypeId = rectDpt[0].Id;
        depart.Name         = '*';
        depart.Department_Name__c  = 'NFM007TestDepart';
        depart.ParentId            = section.Id;
        depart.Department_Class__c = section.Id;
        depart.Hospital__c         = company.Id;
        upsert depart;
        Opportunity opp = new Opportunity();
        opp.AccountId           = depart.Id;
        opp.Department_Class__c = section.Id;
        opp.Hospital__c         = company.Id;
        opp.SAP_Send_OK__c      = false;
        opp.Name                = 'GZ-SP-NFM007_1';
        opp.Trade__c            = '内貿';
        opp.StageName           = '询价';
        opp.ConfirmationofAward__c='OLY中标';
        opp.CloseDate           = date.newinstance(2022, 11, 30);
        insert opp;
        System.Test.startTest();
        opp.ConfirmationofAward__c='竞争对手中标';
        update opp;
        System.Test.stopTest();
    }
}
//end start 20220623
}
force-app/main/default/classes/TenderLostController.cls
New file
@@ -0,0 +1,150 @@
public without sharing class TenderLostController {
    //初始化
    @AuraEnabled
    public static  String InitData(String ParamIdStr) {
        //根据招标项目Id  查  招标项目名称  作为 询价名称
        List<Tender_information__c> tenList = Database.query('Select Id, Name From Tender_information__c Where Id = : ParamIdStr ');
        Opportunity opp = new Opportunity();
        if(tenList.size() > 0){
            opp.Name = tenList[0].Name;
            opp.Bidding_Project_Name_Bid__c = ParamIdStr;
        }
        return JSON.serialize(opp);
    }
    // 已关联的医院
    @AuraEnabled
    public static List<String> LinkedHospitals(String ParamIdStr) {
        List<Tender_information__c> tenList = Database.query('Select Id, Hospital__c, Hospital1__c, Hospital2__c, Hospital3__c, Hospital4__c From Tender_information__c Where Id = : ParamIdStr ');
        List<String> hospitals = new List<String>();
        if(tenList.size() > 0){
            if (String.isNotBlank(tenList[0].Hospital__c)) {
                hospitals.add(tenList[0].Hospital__c);
            }
            if (String.isNotBlank(tenList[0].Hospital1__c)) {
                hospitals.add(tenList[0].Hospital1__c);
            }
            if (String.isNotBlank(tenList[0].Hospital2__c)) {
                hospitals.add(tenList[0].Hospital2__c);
            }
            if (String.isNotBlank(tenList[0].Hospital3__c)) {
                hospitals.add(tenList[0].Hospital3__c);
            }
            if (String.isNotBlank(tenList[0].Hospital4__c)) {
                hospitals.add(tenList[0].Hospital4__c);
            }
        }
        return hospitals;
    }
    //把页面上的数据赋值到询价对象上
    private static Opportunity mergeInfo(Map<String, Object> oppMap){
        Opportunity opp = new Opportunity();
        // 名称
        opp.Name = String.valueOf(oppMap.get('Name'));
        //询价 关联 招标项目
        opp.Bidding_Project_Name_Bid__c = String.valueOf(oppMap.get('Bidding_Project_Name_Bid__c'));
        //页面上获取 资金来源
        opp.Fund_Basis__c = String.valueOf(oppMap.get('Fund_Basis__c'));
        //页面上获取 招标方式
        opp.Sales_Method__c = String.valueOf(oppMap.get('Sales_Method__c'));
        // 科室
        opp.AccountId = String.valueOf(oppMap.get('AccountId'));
        System.debug('lt123test01默认询价内容'+opp);
        // 查找科室相关信息
        Account acc = [select Id, Name, Parent.Parent.State_Master__r.Name, Parent.Department_Class_Label__c from Account where Id = :opp.AccountId];
        System.debug('lt123test02默认询价内容'+opp);
        opp.SAP_Province__c = acc.Parent.Parent.State_Master__r.Name; // SAP上传省
        switch on acc.Parent.Department_Class_Label__c {              // 询价科室分类  询价编码自动生成要用到
            when '消化科' {
                opp.Opportunity_Category__c = 'GI';
            }
            when '呼吸科' {
                opp.Opportunity_Category__c = 'BF';
            }
            when '普外科' {
                opp.Opportunity_Category__c = 'GS';
            }
            when '泌尿科' {
                opp.Opportunity_Category__c = 'URO';
            }
            when '妇科' {
                opp.Opportunity_Category__c = 'GYO';
            }
            when '耳鼻喉科' {
                opp.Opportunity_Category__c = 'ENT';
            }
            when 'ET' {
                opp.Opportunity_Category__c = 'ET';
            }
            when '其他' {
                opp.Opportunity_Category__c = 'OTH';
            }
            when else {
                opp.Opportunity_Category__c = 'OTH';
            }
        }
        opp.StageName = '引合';                                     // 状态
        opp.Purchase_Reason__c = '新期';                            // 购买原因
        opp.Trade__c = '内貿';                                      // 内贸外贸
        opp.Close_Forecasted_Date__c = Date.today().addDays(90);    // 预测OCSM签约日
        opp.CloseDate = Date.today().addDays(120);                  // 预测发货日
        opp.Purchase_Type__c = '一般引合';                          // 订货方式
        opp.Sales_Root__c = '販売店';                               // 渠道为"经销商"
        opp.ifOpenBid__c = '公开招标';                              // 是否公开招标
        opp.LeadSource = '招标网';                                  // 潜在客户来源
        opp.LeakageNumber__c = 1;                                   //漏单数
        opp.Tender_Number__c = 1;                                   //招标数
        //应标数为0   Authorized_DB_No__c为空时为0
        //中标数为0
        opp.ConfirmationofAward_createTime__c = Date.today();       //中标结果确认日
        opp.ConfirmationofAward__c = '竞争对手中标';                 //中标确认结果
        System.debug('lt123opp默认询价内容'+opp);
        return opp;
    }
    //保存数据  JSONData 是 json格式的值
    @AuraEnabled
    public static string SaveData(String JsonData){
        Opportunity opp = new Opportunity();
        try{
            Map<String, Object> oppMap = (Map<String, Object>)JSON.deserializeUntyped(JsonData);
            System.debug('lt123JsonData'+JsonData);
            opp = mergeInfo(oppMap);
            insert opp;
            System.debug('lt123opp.Id'+opp.Id);
            return opp.Id;
        }catch(Exception ex)
        {
            return  '错误:' + ex.getLineNumber()+'  行错误 :   '+ex.getMessage();
        }
    }
    //查询普通科室
    @AuraEnabled
    public  static String SearchPTKS(String content, List<String> hospitals){
        String profile_2S1 = System.Label.ProfileId2S1HP;
        Boolean is_2S1 = profile_2S1.contains(UserInfo.getProfileId()) ? true : false;
        String jsonData = CommonUtils.GetPTKS(content, hospitals, is_2S1);
        System.debug('hospitals: ' + hospitals);
        System.debug('offices: ' + jsonData);
        return jsonData;
    }
    //查询父类
    // @AuraEnabled
    // public  static String SearchParent(String Id){
    //     String jsonData = CommonUtils.GetParent(Id);
    //     return jsonData;
    // }
}
force-app/main/default/classes/TenderLostControllerTest.cls
New file
@@ -0,0 +1,65 @@
@isTest
private class TenderLostControllerTest {
    @isTest
    static void TestMethod1() {
        //创建客户
        Account hospital = new Account();
        hospital.recordtypeId = [Select Id FROM RecordType WHERE IsActive = true and SobjectType = 'Account' and DeveloperName = 'HP'].id;
        hospital.Name = 'test hospital';
        hospital.Is_Active__c = '有効';
        hospital.Attribute_Type__c = '卫生部';
        hospital.Speciality_Type__c = '综合医院';
        hospital.Grade__c = '一级';
        hospital.OCM_Category__c = 'SLTV';
        hospital.Is_Medical__c = '医疗机构';
        hospital.Town__c = '东京';
        hospital.Department_Name__c = 'testKS';
        insert hospital;
        //创建招标项目
        Tender_information__c Ten = new Tender_information__c();
        Ten.Name = '123456';
        Ten.ProjectId__c = '38_99df2844cf784982acdc61d00d7a7dbb';
        ten.Hospital__c = hospital.Id;
        ten.Hospital1__c = hospital.Id;
        ten.Hospital2__c = hospital.Id;
        ten.Hospital3__c = hospital.Id;
        ten.Hospital4__c = hospital.Id;
        insert Ten;
        //询价
        Opportunity opp = new Opportunity();
        opp.Name = 'Testname0922';
        opp.Fund_Basis__c = '政府資金';
        opp.Sales_Method__c = '政府招标';
        opp.StageName = '引合';
        opp.Opportunity_No__c = '0801';
        opp.Purchase_Reason__c = '新期';
        opp.Trade__c = '内貿';
        opp.Close_Forecasted_Date__c = Date.today().addDays(90);
        opp.CloseDate = Date.today().addDays(120);
        opp.Purchase_Type__c = '一般引合';
        opp.Sales_Root__c = '販売店';
        opp.ifOpenBid__c = '公开招标';
        opp.LeadSource = '招标网';
        opp.LeakageNumber__c = 1;
        opp.Tender_Number__c = 1;
        opp.ConfirmationofAward_createTime__c = Date.today();
        opp.ConfirmationofAward__c = '竞争对手中标';
        insert opp;
        Map<String, Object> oppMap = new Map<String, Object>();
        oppMap.put('AccountId',hospital.Id);
        String str1 = JSON.serialize(opp);
        String str2 = JSON.serialize(oppMap);
        TenderLostController.InitData(String.valueOf(Ten.Id));
        TenderLostController.LinkedHospitals(String.valueOf(Ten.Id));
        TenderLostController.SaveData(str1);
        TenderLostController.SaveData(str2);
    }
}
force-app/main/default/classes/TenderResultConfirmTaskBatch.cls
New file
@@ -0,0 +1,165 @@
/**
 * 2022-06-15 sx 询价跟进任务
 */
global class TenderResultConfirmTaskBatch implements Database.Batchable<sObject> {
    Integer opporTotal = 0;
    Integer taskTotal = 0;
    BatchIF_Log__c log = new BatchIF_Log__c();
    public TenderResultConfirmTaskBatch() {
    }
    //20220715 you 招标任务 start
    List<String> TenderIds = new List<String>();
    global TenderResultConfirmTaskBatch(List<String> tenIds){
        this.TenderIds = tenIds;
    }
    //20220715 you 招标任务 end
    global Database.QueryLocator start(Database.BatchableContext bc){
        String query = 'Select Id, Opportunity__c, Tender_information__c, '
                     + 'Tender_information__r.status__c, Tender_information__r.TenderManageCode__c,Tender_information__r.RecordTypeId, Tender_information__r.CreatedDate,'
                     + 'Opportunity__r.OwnerId, Opportunity__r.AccountId, Opportunity__r.StageName__c, '
                     + 'Opportunity__r.Assistant_Applied_Date__c, Opportunity__r.Cnt_Lost_cancel_Draft__c, Opportunity__r.ConfirmationofAward__c, '
                     + 'Opportunity__r.Contract_DB_complite_day__c, Opportunity__r.Contract_Authorize_Lock__c, Opportunity__r.LeakageNumber__c, '
                     + 'Opportunity__r.ConfirmationofAward_createTime__c '
                     + 'FROM Tender_Opportunity_Link__c '
                     + 'WHERE Tender_information__r.InfoType__c = \'3:结果\' '
                     + 'AND (Tender_information__r.subInfoType__c = \'3-5:中标通知\' OR Tender_information__r.subInfoType__c = \'3-6:合同公告\') '
                     + 'AND Tender_information__r.RecordTypeId = \'01210000000VLUI\' ';
        //20220715 you 招标任务 start
        if(TenderIds !=null && TenderIds.size() > 0){
              query += 'AND Opportunity__c in :TenderIds';
            //query += 'AND Tender_information__c in :TenderIds ';
        }else{
             query += 'AND Tender_information__r.LastModifiedDate = LAST_N_DAYS:2';
        }
        query += ' ORDER BY Opportunity__c, Tender_information__r.CreatedDate';
        //20220715 you 招标任务 end
        return Database.getQueryLocator(query);
    }
    global void execute(Database.BatchableContext BC, list<Tender_Opportunity_Link__c> toppLinkList){
        log.Type__c='TenderResultConfirm_Task';
        String logstr = 'Batch execute start' + '\r\n 查询结果 :' + toppLinkList;
        Set<Id> oppIds = new Set<Id>();
        for (Tender_Opportunity_Link__c tol : toppLinkList) {
            oppIds.add(tol.Opportunity__c);
        }
        //20220718  筛选一下有无任务的询价,取消也需要新建
        List<Task__c> taskList = [
                SELECT Id,OpportunityId__c,taskStatus__c
                FROM task__c
                WHERE OpportunityId__c in :oppIds
                AND (RecordType.Name = '中标结果确认' OR RecordType.Name = '失单报告任务')
                AND (taskStatus__c = '02 接受' OR taskStatus__c = '03 完成')];
        system.debug('test1-----'+taskList);
        Map<String,Task__c> mapTask = new Map<String,Task__c>();
        for(Task__c t: taskList){
            mapTask.put(t.OpportunityId__c, t);
        }
        // 记录类型:中标结果确认
        Id winBiddingTask_TaskId = Schema.SObjectType.task__c.getRecordTypeInfosByDeveloperName().get('winBiddingTask').getRecordTypeId();
        Map<Id, Opportunity> oppMap = new Map<Id, Opportunity>();
        Map<Id, Task__c> taskMap = new Map<Id, Task__c>();
        for(Tender_Opportunity_Link__c topp : toppLinkList){
            system.debug('test3'+topp.Opportunity__c);
            logstr += 'Batch execute ' + '\r\n 询价进入for----- :'+ topp;
            // 已存在有效状态任务的询价,不用再次产生任务
            if (mapTask.isEmpty()
                || (!mapTask.isEmpty() && !mapTask.containsKey(topp.Opportunity__c))){
                //1.内部确认状态为05.询价中且关联询价的状态1为询价 且 价格申请 不等于 真 -- > 创建并派发任务
                if (topp.Tender_information__r.status__c == '05.询价中' && topp.Opportunity__r.StageName__c == '询价' && topp.Opportunity__r.Assistant_Applied_Date__c == null && topp.Opportunity__r.LeakageNumber__c !=1){
                    logstr += 'Batch execute ' + '\r\n 询价进入第一个判断条件----- :'+ topp.Opportunity__c ;
                    Task__c tempTask = new Task__c();
                    tempTask.RecordTypeId = winBiddingTask_TaskId;
                    tempTask.taskDifferent__c = '被动任务';
                    tempTask.taskStatus__c = '02 接受';       //任务状态2
                    tempTask.assignee__c = topp.Opportunity__r.OwnerId;    //被分配者
                    tempTask.account__c = topp.Opportunity__r.AccountId;
                    tempTask.Name = '中标结果确认:' + topp.Tender_information__r.TenderManageCode__c;  //招标项目.SFDC编码
                    tempTask.OwnerId = topp.Opportunity__r.OwnerId;   //所有人
                    tempTask.OpportunityId__c = topp.Opportunity__c;
                    tempTask.Tender_information_Task__c = topp.Tender_information__c;       //招标项目
                    tempTask.ConfirmDate__c = Date.today();
                    if (taskMap.isEmpty() || !taskMap.containsKey(topp.Opportunity__c)) {
                       taskMap.put(topp.Opportunity__c, tempTask);
                    }
                    //更新询价  Task_createTime__c
                    if(oppMap.isEmpty() || !oppMap.containsKey(topp.Opportunity__c)){
                        Opportunity tempOpp  = new Opportunity();
                        tempOpp.Id = topp.Opportunity__c;
                        tempOpp.Task_createTime__c = Date.today();
                        oppMap.put(topp.Opportunity__c, tempOpp);
                    }
                }
            }
            //2. 存在已提交的失单报告或者询价状态1=失单 -- >中标确认:竞争对手中标
            // 招标项目中的中标确认更改在Batch中更新
            if (topp.Opportunity__r.Cnt_Lost_cancel_Draft__c > 0 || topp.Opportunity__r.StageName__c == '失单'){
                logstr += 'Batch execute ' + '\r\n 询价进入第二个判断条件----- :'+ topp.Opportunity__c ;
                //中标确认字段赋值竞争对手中标
                if(oppMap.isEmpty() || !oppMap.containsKey(topp.Opportunity__c)){
                    Opportunity tempOpp  = new Opportunity();
                    tempOpp.Id = topp.Opportunity__c;
                    tempOpp.ConfirmationofAward__c = '竞争对手中标';
                    oppMap.put(topp.Opportunity__c, tempOpp);
                }
            }
            //3.已完成合同申请 --> 中标确认:OLY中标
            // 招标项目中的中标确认更改在Batch中更新
            if (topp.Opportunity__r.Contract_DB_complite_day__c != null && topp.Opportunity__r.Contract_Authorize_Lock__c){
                logstr += 'Batch execute ' + '\r\n 询价进入第三个判断条件----- :'+ topp.Opportunity__c ;
                //中标确认字段赋值竞争对手中标
                if(oppMap.isEmpty() || !oppMap.containsKey(topp.Opportunity__c)){
                    Opportunity tempOpp  = new Opportunity();
                    tempOpp.Id = topp.Opportunity__c;
                    tempOpp.ConfirmationofAward__c = 'OLY中标';
                    oppMap.put(topp.Opportunity__c, tempOpp);
                }
            }
        }
        try {
            if (!taskMap.isEmpty()) {
                insert taskMap.values();
                logstr += 'Batch execute ' + '\r\n 任务数据 :'+ taskMap.size() + taskMap.values() ;
            }
            if (!oppMap.isEmpty()) {
                update oppMap.values();
                logstr += 'Batch execute ' + '\r\n 询价数据 :'+ oppMap.size() + oppMap.values() ;
            }
            logstr += '\nend';
        } catch(Exception ex) {
            //发生错误的情况
            System.debug(Logginglevel.ERROR, 'NFM112_' + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'NFM112_' + ':' + ex.getStackTraceString());
            logstr += ex.getMessage();
            log.ErrorLog__c += ex.getMessage() + '\n';
            log.ErrorLog__c += ex.getStackTraceString() + '\n';
        }
        log.Log__c = logstr;
        insert log;
    }
    global void finish(Database.BatchableContext BC) {
        system.debug('opporTotal======'+opporTotal);
        system.debug('taskTotal======'+taskTotal);
    }
}
force-app/main/default/classes/TenderResultConfirmTaskBatchTest.cls
New file
@@ -0,0 +1,170 @@
@isTest
private class TenderResultConfirmTaskBatchTest {
    @IsTest
    static void myTest1() {
        StaticParameter.EscapeTOLinkTrigger = true;
        ControllerUtil.EscapeNFM001Trigger = true;
        ControllerUtil.EscapeMaintenanceContractAfterUpdateTrigger = true;
        StaticParameter.EscapeNFM001Trigger = true;
        StaticParameter.EscapeNFM001AgencyContractTrigger = true;
        StaticParameter.EscapeNFM001AgencyContractTrigger2 = true;
        StaticParameter.EscapeMaintenanceContractAfterUpdateTrigger = true;
        Oly_TriggerHandler.bypass('TenderInformationHandler');
        Profile p = [select id from Profile where id =:System.Label.ProfileId_SystemAdmin];
        String loginId = UserInfo.getUserId();
        User sys = [select id from User where Id = :loginId];
        User u1 = new User(Test_staff__c = true);
        u1.LastName = '123';
        u1.FirstName = '2';
        u1.Batch_User__c = true;
        u1.Alias = '2';
        u1.Email = 'shashiming@prec-tech.com';
        u1.Username = 'test_user1@olympus.com.cn.tenopplink';
        u1.CommunityNickname = 'あ1';
        u1.IsActive = true;
        u1.EmailEncodingKey = 'ISO-2022-JP';
        u1.TimeZoneSidKey = 'Asia/Tokyo';
        u1.LocaleSidKey = 'ja_JP';
        u1.LanguageLocaleKey = 'ja';
        u1.ProfileId = p.id;
        u1.Job_Category__c = '销售服务';
        u1.Province__c = '東京';
        insert u1;
        User u2 = new User(Test_staff__c = true);
        u2.LastName = '_サンブリッジ';
        u2.FirstName = 'い';
        u2.Batch_User__c = true;
        u2.Alias = 'い';
        u2.Email = 'shashiming@prec-tech.com';
        u2.Username = 'test_user2@olympus.com.cn.tenopplink';
        u2.CommunityNickname = 'い';
        u2.IsActive = true;
        u2.EmailEncodingKey = 'ISO-2022-JP';
        u2.TimeZoneSidKey = 'Asia/Tokyo';
        u2.LocaleSidKey = 'ja_JP';
        u2.LanguageLocaleKey = 'ja';
        u2.ProfileId = p.id;
        u2.Job_Category__c = '销售推广';
        u2.Province__c = '東京';
        u2.IsActive = true;
        insert u2;
        //创建招标项目1
        Tender_information__c info1 = new Tender_information__c();
        info1.Name = 'TEST001';
        info1.OpportunityStatus__c = '跟进中';
        info1.InfoType__c = '3:结果';
        info1.subInfoType__c = '3-5:中标通知';
        info1.OwnerId = u1.Id;
        info1.OpportunityNum__c = 1;
        info1.ResultDate__c = Date.today();
        insert info1;
        //询价1
        Opportunity opp1 = new Opportunity(
            StageName = '引合',
            Name = 'tenderTest询价1',
            ETPromoteSale__c  = true,
            Close_Forecasted_Date__c = Date.today().addDays(-5),
           // Bidding_Project_Name_Bid__c = info1.Id,
           CloseDate = Date.today()
        );
        insert opp1;
        Test.StartTest();
        System.runAs(u1){
            // 插入关联关系
            Tender_Opportunity_Link__c link1 = new Tender_Opportunity_Link__c();
            link1.Tender_information__c = info1.Id;
            link1.Opportunity__c = opp1.Id;
            insert link1;
        }
        System.runAs(u2){
            //新建招标项目2
            Tender_information__c info2 = new Tender_information__c();
            info2.Name = 'TEST002';
            info2.InfoType__c = '3:结果';
            info2.subInfoType__c = '3-5:中标通知';
            info2.ResultDate__c = Date.today();
            insert info2;
            //新建询价2
            Opportunity opp2 = new Opportunity(
                StageName = '引合',
                Name = 'tenderTest询价2',
                Contract_DB_complite_day__c = Date.today(),
                Close_Forecasted_Date__c = Date.today().addDays(-5),
                CloseDate = Date.today(),
                Contract_Authorize_Lock__c = true
            );
            insert opp2;
            // 插入关联关系
            Tender_Opportunity_Link__c link2 = new Tender_Opportunity_Link__c();
            link2.Tender_information__c = info2.Id;
            link2.Opportunity__c = opp2.Id;
            insert link2;
        }
        //新建询价3
        Opportunity opp3 = new Opportunity(
            StageName = '敗戦',
            Name = 'tenderTest询价3',
            Close_Forecasted_Date__c = Date.today().addDays(-5),
            CloseDate = Date.today()
        );
        insert opp3;
        //新建 询价失单/取消报告
        Lost_cancel_report__c lcr = new Lost_cancel_report__c(
            Opportunity__c = opp3.Id
        );
        insert lcr;
        opp3.Lost_Cancel_Report__c = lcr.Id;
        update opp3;
        // //新建询价4
        // Opportunity opp4 = new Opportunity(
        //     StageName = '敗戦',
        //     Name = 'tenderTest询价4',
        //     Close_Forecasted_Date__c = Date.today().addDays(-5),
        //     CloseDate = Date.today(),
        //     ConfirmationofAward__c = '竞争对手中标'
        // );
        // insert opp4;
        // //新建 询价失单/取消报告
        // Lost_cancel_report__c lcr1 = new Lost_cancel_report__c(
        //     Opportunity__c = opp4.Id
        // );
        // insert lcr1;
        // opp4.Lost_Cancel_Report__c = lcr.Id;
        // // update opp4;
        List<Tender_Opportunity_Link__c> slist = [select id,name,Tender_information__r.InfoType__c,Tender_information__r.subInfoType__c,Tender_information__r.status__c,Tender_information__r.LastModifiedDate,Tender_information__r.OpportunityStatus__c,Tender_information__r.OpportunityNum__c,
                                                    Opportunity__r.StageName__c,Opportunity__r.If_Need_PriceApply__c,Opportunity__r.Contract_DB_complite_day__c,Opportunity__r.Contract_Authorize_Lock__c
                                                    from Tender_Opportunity_Link__c];
        System.assertEquals(2, slist.size());
        System.assertEquals('3:结果', slist[1].Tender_information__r.InfoType__c);
        System.assertEquals('3-5:中标通知', slist[1].Tender_information__r.subInfoType__c);
        // System.assertEquals('跟进中',slist[0].Tender_information__r.OpportunityStatus__c);
        // System.assertEquals(1,slist[0].Tender_information__r.OpportunityNum__c);
        // System.assertEquals('05.询价中',slist[0].Tender_information__r.status__c);
        // System.assertEquals('询价',slist[0].Opportunity__r.StageName__c);
        System.assertEquals(Date.today(),slist[1].Opportunity__r.Contract_DB_complite_day__c);
        System.assertEquals(true,slist[1].Opportunity__r.Contract_Authorize_Lock__c);
        Database.executeBatch(new TenderResultConfirmTaskBatch());
        Test.stopTest();
    }
}
force-app/main/default/lwc/tenderLost/__tests__/tenderLost.test.js
New file
@@ -0,0 +1,25 @@
import { createElement } from 'lwc';
import TenderLost from 'c/tenderLost';
describe('c-tender-lost', () => {
    afterEach(() => {
        // The jsdom instance is shared across test cases in a single file so reset the DOM
        while (document.body.firstChild) {
            document.body.removeChild(document.body.firstChild);
        }
    });
    it('TODO: test case generated by CLI command, please fill in test logic', () => {
        // Arrange
        const element = createElement('c-tender-lost', {
            is: TenderLost
        });
        // Act
        document.body.appendChild(element);
        // Assert
        // const div = element.shadowRoot.querySelector('div');
        expect(1).toBe(1);
    });
});
force-app/main/default/lwc/tenderLost/tenderLost.html
New file
@@ -0,0 +1,75 @@
<template>
    <div class="exampleHolder" if:true={IsLoading} >
      <lightning-spinner alternative-text="Loading" size="large"></lightning-spinner>
    </div>
    <div style="padding:30px">
      <div style="float:right" >
        <div class="demo-only demo-only_viewport" style="height:4.5rem;" if:true = {Tongzhishow}>
          <div class="slds-notification-container" style={IsLeftStyle}>
            <div aria-live="assertive" aria-atomic="true" class="slds-assistive-text">提示</div>
            <section class="slds-notification" role="dialog" aria-labelledby="noti77" aria-describedby="dialog-body-id-43" >
              <div class="slds-notification__body" id="dialog-body-id-43" >
                <a class="slds-notification__target slds-media" href="#" style={BgColorStyle}>
                  <span class="slds-icon_container slds-icon-standard-task slds-media__figure" title="task">
                      <lightning-icon icon-name={TongzhiIcon} alternative-text="Account" title="Account"></lightning-icon>
                  </span>
                  <div class="slds-media__body">
                    <h2 class="slds-text-heading_small slds-m-bottom_xx-small" id="noti77">
                      <span class="slds-assistive-text">task notification:</span>提示</h2>
                    <p>{SaveShowText}</p>
                  </div>
                </a>
                <button class="slds-button slds-button_icon slds-button_icon-container slds-notification__close" title="close">
                    <lightning-icon icon-name="utility:close" alternative-text="close" title="close"  size="x-small" onclick={CloseAlert}></lightning-icon>
                </button>
              </div>
            </section>
          </div>
        </div>
      </div>
      <!-- 页面主体 -->
      <div style="width: 495px;padding:1px">
        <lightning-combobox
          name="fundBasic"
          label="资金来源:"
          placeholder="请选择"
          value={opp.Fund_Basis__c}
          options={RelateOption}
          onchange={handleRelationFn}
          style="width: 495px;padding:1px"
        >
        </lightning-combobox>
      </div>
      <div style="width: 495px;padding:1px">
        <lightning-combobox
          name="salesMethod"
          label="招标方式:"
          placeholder="请选择"
          value={opp.Sales_Method__c}
          options={RelateOption1}
          onchange={handleRelationFn1}
          style="width: 495px;padding:1px"
        >
        </lightning-combobox>
      </div>
      <div style="width: 495px;padding:1px">
      <!-- <c-jzlookup if:true={isShi} data-parent-id="lookup3" label="关联普通科室" placeholder="请选择普通科室.."  onsearchchange={onsearchchangePTKS} searchdata={searchdataPTKS} option={optionPTKS} onselected={selectedPTKS}> </c-jzlookup> -->
      <c-jzlookup data-parent-id="lookup3" label="科室:" placeholder="请选择科室.."  onsearchchange={onsearchchangePTKS} searchdata={searchdataPTKS} option={optionPTKS} onselected={selectedPTKS} > </c-jzlookup>
      <!-- <c-jzlookuplightning ata-parent-id="lookup1"  onsearchchange={onsearchchangePTKS} objectname="Opportunity" fieldname="AccountId"  >   </c-jzlookuplightning> -->
    </div>
      <button
      class="slds-button slds-button_brand"
      onclick={saveFn}
      style="margin-top: 10px">
      保存
      </button>
      <!-- 页面主体 -->
    </div>
  </template>
force-app/main/default/lwc/tenderLost/tenderLost.js
New file
@@ -0,0 +1,169 @@
import { LightningElement, api, track } from 'lwc';
import SaveData from '@salesforce/apex/TenderLostController.SaveData';
import SearchPTKS from '@salesforce/apex/TenderLostController.SearchPTKS';
// import SearchParent from '@salesforce/apex/TenderLostController.SearchParent';
import InitData from '@salesforce/apex/TenderLostController.InitData';
import LinkedHospitals from '@salesforce/apex/TenderLostController.LinkedHospitals';
export default class TenderLost extends LightningElement {
    //资金来源选项
    RelateOption=[
        {label:"政府拨款",value:"政府資金"},
        {label:"医院资金",value:"病院資金"},
        {label:"国际资金",value:"国際資金"},
        {label:"银行资金",value:"銀行資金"},
        {label:"公司/个人投资",value:"会社/個人資金"},
        {label:"融资租赁",value:"融资租赁(リース)"},
        {label:"其他",value:"その他"},
    ];
    //招标方式选项
    RelateOption1=[
        {label:"政府招标",value:"政府招标"},
        {label:"院内招标",value:"院内招标"},
        {label:"竟争性谈判",value:"竟争性谈判(非招标)"},
        {label:"单一来源采购",value:"单一来源采购"},
        {label:"私立医院采购",value:"私立医院采购"},
        {label:"耗材采购",value:"耗材采购"},
    ];
    // 页面对象
    opp = {};
    hospitals = [];
    //资金来源
    handleRelationFn(event){
        var value = event.target.value;
        this.opp.Fund_Basis__c = value;
    }
    //招标方式
    handleRelationFn1(event){
        var value = event.target.value;
        this.opp.Sales_Method__c = value;
    }
    //从url上取得ID
    getQueryVariable(variable)
    {
        var query = window.location.search.substring(1);
        var vars = query.split("&");
        for (var i=0;i<vars.length;i++) {
                var pair = vars[i].split("=");
                if(pair[0] == variable){return pair[1];}
        }
        return(false);
    }
    //初始化
    connectedCallback(){
        this.tenId = this.getQueryVariable('id');
        InitData({ParamIdStr:this.tenId}).then(response=>{
            this.opp=JSON.parse(response);
        });
        LinkedHospitals({ParamIdStr:this.tenId}).then(response=>{
            this.hospitals = response;
            console.log('get linked hospital:' + this.hospitals);
        });
    }
    //关联普通科室
    optionPTKS = [{lableOne:"Name",lableTwo:"Acc_Record_Type__c"}];
    searchdataPTKS=[];
    onsearchchangePTKS(event){
    var searchContentStr = event.detail.searchContent;
    console.log('hospitals: ' + this.hospitals);
       SearchPTKS({content:searchContentStr, hospitals:this.hospitals}).then(response=>{
            var datas = JSON.parse(response);
            this.searchdataPTKS = datas;
            this.template.querySelector('[data-parent-id="lookup3"]').refreshdata(this.searchdataPTKS);
        })
    }
    PTKSId = '';
    selectedPTKS(event)
    {
        console.warn(event.detail.selectdata.Id);
        this.opp.AccountId = event.detail.selectdata.Id;
    }
    // InitPTKS()
    // {
    //     SearchPTKS({content:undefined}).then(response=>{
    //     var datas = JSON.parse(response);
    //         this.searchdataPTKS = datas;
    //         this.template.querySelector('[data-parent-id="lookup3"]').refreshdata(this.searchdataPTKS);
    //     })
    // }
    //关联普通科室
    //保存数据逻辑
    saveFn(){
        if(this.opp.Fund_Basis__c == undefined || this.opp.Sales_Method__c == undefined || this.opp.AccountId == undefined){
            this.Alert("请不要输入空哦。",false,true);
        }else{
            this.OnLoading(true);
            SaveData({JsonData:JSON.stringify(this.opp)}).then((response)=>{
                if (response != '' && response.indexOf('错误') < 0) {
                    this.OnLoading(false);
                    console.log(response);
                    this.Alert("保存成功",false,true);
                    window.open('/apex/PCLLostReportPage?pageStatus=Create&oppId=' + response + '&lostType=失单');
                    // window.location.hash = "Refresh"+"=="+response;
                    top.window.close();
                }else{
                    this.Alert(response,true);
                }
            });
        }
    }
    //-------- 保存提示框 --------
    //提示
    SaveShowText="保存成功";//提示框的文本
    Tongzhishow=false;  //提示显示的标识
    TongzhiIcon = 'standard:account' //提示框的图标
    IsLeftStyle = "" //提示框的样式
    BgColorStyle = ""
    //弹框提示 content 内容 error 是否是错误提示框  left 是否居左
    Alert(content,error = false,left = false){
        this.SaveShowText = content;
        this.Tongzhishow = true;
        if (error) {
            this.TongzhiIcon = "standard:first_non_empty";
            this.BgColorStyle = "background-color:#f88568";
        }else{
            this.TongzhiIcon = "standard:account";
            this.BgColorStyle = "background-color:#69e669";
        }
        if (left) {
            this.IsLeftStyle = "left: 0.25rem"
        }else{
            this.IsLeftStyle = ""
        }
    }
    //关闭提示框
    CloseAlert(){
        this.closeOffRefresh();
    }
    closeOffRefresh(){
        if (this.Tongzhishow == true) {
            this.Tongzhishow = false;
        }
        if (this.SaveShowText != "") {
            this.SaveShowText = "";
        }
    }
    //加载
    IsLoading = false;
    OnLoading(flag) {
        this.IsLoading = flag;
    }
    //-------- 保存提示框 --------
}
force-app/main/default/lwc/tenderLost/tenderLost.js-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>55.0</apiVersion>
    <isExposed>false</isExposed>
</LightningComponentBundle>
force-app/main/default/pages/TenderLostPage.page
New file
@@ -0,0 +1,26 @@
<apex:page showHeader="false" sidebar="false" id="TenderLostApp" title="招标项目失单">
    <apex:includeLightning />
    <div style="width:100%;height:100%;" id="TenderLostApp" />
    <script>
        $Lightning.use("c:TenderLostApp", function () {
            $Lightning.createComponent("c:tenderLost",
                {},
                "TenderLostApp",
                function (cmp) {
                    console.log('Component created, do something cool here');
                });
        });
        // var interval = setInterval(()=>{
        //     var hrefStr = window.location.href;
        //     if (hrefStr.indexOf("Refresh") != -1) {
        //         // var arr = hrefStr.split("==");
        //         // window.open('/a1U/e?retURL=%2F' + arr[1] + '&RecordType=01210000000R4hM');
        //         top.window.close();
        //         clearInterval(interval);
        //     }
        // },1000);
    </script>
</apex:page>