public with sharing class SetPersonalTargetEngController { // 当前期 public String currentPeriod { get; private set; } // 上年度按钮制御 public Boolean previousRendered { get; private set; } // 下年度按钮制御 public Boolean nextRendered { get; private set; } // 数据集 public List dataBeans { get; set; } // 金额分类 public List opportunity_category { get; private set; } // 是否是过去年度 public Boolean isPast { get; private set; } // 年度変化時セーブかどうか public Boolean saveFlg { get; set; } // 本部の選択値 public String salesDpt { get; set; } // 職位のチェックボックス public List plist { get; set; } // 登陆用户 public User loginUser { get; set; } // checkAll値保持用 public Boolean checkAll { get; set; } // 製品担当の選択値 public String productUser { get; set; } // 医院担当 プルダウン public static List productUserOptions { get; private set; } static { productUserOptions = new List(); productUserOptions.add(new SelectOption('医院担当','医院担当')); productUserOptions.add(new SelectOption('医院担当以外','医院担当以外')); } public SetPersonalTargetEngController() { //Apexpages.currentPage().getHeaders().put('X-UA-Compatible', 'IE=8'); } // ユーザ数 public Integer getUserSize() { return users.size(); } // 職位数 public Integer getPSize() { return plist.size(); } // 本部プルダウン public static List salesDptOpts { get; private set; } static { salesDptOpts = new List(); salesDptOpts.add(new SelectOption('','--无--')); salesDptOpts.add(new SelectOption('1.华北','1.华北')); salesDptOpts.add(new SelectOption('2.东北','2.东北')); salesDptOpts.add(new SelectOption('3.西北','3.西北')); salesDptOpts.add(new SelectOption('4.西南','4.西南')); salesDptOpts.add(new SelectOption('5.华东','5.华东')); salesDptOpts.add(new SelectOption('6.华南','6.华南')); } // 现在年度 private Integer currentYear; // 当前年度 private Integer iYear; // 当前月份 private Integer iMonth; // 当前日期 private Integer iDay; // 4月可编辑期限 private Integer iBuffer; private RecordType rt; // 目标的数据类型 private User[] users; // 担当人员 private Map> proportion; // 比重 private String adminDpt = null; // 既存目标数据 private Map oppMap; // 金额分类 //private static String[] amountCategory = new String[] {'GI','ET','BF','GS','URO','GYN','ENT','OTH'}; private static String[] amountCategory = new String[] {'ENG'}; // 画面初始化 public Pagereference init() { // 现在时间 Date dateNow = Date.today(); Integer year = dateNow.year(); Integer month = dateNow.month(); if (month < 4) { year -= 1; } // 初始化 currentYear = year; iYear = year; iMonth = month; iDay = dateNow.day(); iBuffer = Integer.valueOf(System.Label.SetPersonalTarget_buffer_day); isPast = false; // if (month == 3) isPast = true; currentPeriod = String.valueOf(iYear - 1867 + 'P'); previousRendered = true; nextRendered = true; saveFlg = false; // 金额分类 opportunity_category = amountCategory; // 每月比重 if (proportion == null) { proportion = new Map>(); String strObjectiveProportionGI = System.Label.ObjectiveProportionGI; List objectiveProportionGI = strObjectiveProportionGI.split(','); List doubleGI = new List(); for (String strGI : objectiveProportionGI) { doubleGI.add(Double.valueOf(strGI)); } proportion.put('GI', doubleGI); String strObjectiveProportionET = System.Label.ObjectiveProportionET; List objectiveProportionET = strObjectiveProportionET.split(','); List doubleET = new List(); for (String strET : objectiveProportionET) { doubleET.add(Double.valueOf(strET)); } proportion.put('ET', doubleET); String strObjectiveProportionBF = System.Label.ObjectiveProportionBF; List objectiveProportionBF = strObjectiveProportionBF.split(','); List doubleBF = new List(); for (String strBF : objectiveProportionBF) { doubleBF.add(Double.valueOf(strBF)); } proportion.put('BF', doubleBF); String strObjectiveProportionGS = System.Label.ObjectiveProportionGS; List objectiveProportionGS = strObjectiveProportionGS.split(','); List doubleGS = new List(); for (String strGS : objectiveProportionGS) { doubleGS.add(Double.valueOf(strGS)); } proportion.put('GS', doubleGS); String strObjectiveProportionURO = System.Label.ObjectiveProportionURO; List objectiveProportionURO = strObjectiveProportionURO.split(','); List doubleURO = new List(); for (String strURO : objectiveProportionURO) { doubleURO.add(Double.valueOf(strURO)); } proportion.put('URO', doubleURO); String strObjectiveProportionGYN = System.Label.ObjectiveProportionGYN; List objectiveProportionGYN = strObjectiveProportionGYN.split(','); List doubleGYN = new List(); for (String strGYN : objectiveProportionGYN) { doubleGYN.add(Double.valueOf(strGYN)); } proportion.put('GYN', doubleGYN); String strObjectiveProportionENT = System.Label.ObjectiveProportionENT; List objectiveProportionENT = strObjectiveProportionENT.split(','); List doubleENT = new List(); for (String strENT : objectiveProportionENT) { doubleENT.add(Double.valueOf(strENT)); } proportion.put('ENT', doubleENT); String strObjectiveProportionOTH = System.Label.ObjectiveProportionOTH; List objectiveProportionOTH = strObjectiveProportionOTH.split(','); List doubleOTH = new List(); for (String strOTH : objectiveProportionOTH) { doubleOTH.add(Double.valueOf(strOTH)); } proportion.put('OTH', doubleOTH); // CHAN-BBLCYP 2019048 LHJ Start //String strObjectiveProportionENG = System.Label.ObjectiveProportionENG; String strObjectiveProportionENG = System.Label.ObjectiveProportionENGENG; // CHAN-BBLCYP 2019048 LHJ End List objectiveProportionENG = strObjectiveProportionENG.split(','); List doubleENG = new List(); for (String strENG : objectiveProportionENG) { doubleENG.add(Double.valueOf(strENG)); } proportion.put('ENG', doubleENG); } // 職位 if (plist == null) { plist = new List(); plist.add(new Position('一般', true)); plist.add(new Position('高级', true)); plist.add(new Position('主管', true)); plist.add(new Position('副经理', false)); plist.add(new Position('经理', false)); plist.add(new Position('副部长', false)); plist.add(new Position('部长', false)); } // 当前用户信息 if (loginUser == null) { loginUser = [Select Id, Salesdepartment__c, Province__c, ProfileId From User where Id = :Userinfo.getUserId()]; //loginUser.Province__c = ''; } adminDpt = loginUser.Salesdepartment__c; if (String.isBlank(adminDpt) && (loginUser.ProfileId == System.Label.ProfileId_SystemAdmin || loginUser.ProfileId == System.Label.ProfileId_103 ) ) { adminDpt = '4.华东'; } users = this.getUserList(false, false); // 目标的数据类型 if (rt == null) { rt = [select Id from RecordType where SobjectType = 'Opportunity' and IsActive = true and DeveloperName = 'Target']; } // 数据赋值 setBean(iYear); // 保存成功のメッセージ String s = System.currentPageReference().getParameters().get('s'); if (s == '1') { ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, '保存成功。')); } return null; } // 点击上年度 public void previous() { if (saveFlg) { this.saveLogic(); } iYear -= 1; currentPeriod = String.valueOf(iYear - 1867 + 'P'); // 是否是过去数据 isPast = false; if (iYear < currentYear && !(currentYear - iYear == 1 && iMonth == 4 && iDay <= iBuffer)) { isPast = true; }// else if (iYear == currentYear) { // if (Date.today().month() == 3) { // isPast = true; // } // } previousRendered = true; nextRendered = true; // 数据赋值 setBean(iYear); } // 点击下年度 public void next() { if (saveFlg) { this.saveLogic(); } iYear += 1; currentPeriod = String.valueOf(iYear - 1867 + 'P'); // 是否是过去数据 isPast = false; if (iYear < currentYear && !(currentYear - iYear == 1 && iMonth == 4 && iDay <= iBuffer)) { isPast = true; }// else if (iYear == currentYear) { // if (Date.today().month() == 3) { // isPast = true; // } // } previousRendered = true; nextRendered = true; // 只显示到现在时间的下一年数据 if (iYear > currentYear) { nextRendered = false; } // 数据赋值 setBean(iYear); } // 本部プルダウン変更時の処理、システム管理者専用 public void searchByDpt() { if (saveFlg) { this.saveLogic(); } users = this.getUserList(true, false); // 数据赋值 setBean(iYear); } // 省プルダウン変更時の処理 public void searchByProvince() { if (saveFlg) { this.saveLogic(); } users = this.getUserList(false, true); // 数据赋值 setBean(iYear); } // 職位変更時の処理 public void searchByFilter() { if (saveFlg) { this.saveLogic(); } users = this.getUserList(false, false); // 数据赋值 setBean(iYear); } // 点击保存按钮 public Pagereference saveBtn() { this.saveLogic(); PageReference ref = new Pagereference('/apex/SetPersonalTargetEng?s=1'); ref.setRedirect(true); return ref; } // 点击返回按钮 public Pagereference backBtn() { // HOMEに戻る PageReference ref = new Pagereference('/home/home.jsp'); ref.setRedirect(true); return ref; } // ユーザの検索 private List getUserList(Boolean searchByDpt, Boolean searchByProvince) { String soql = 'select Id, Salesdepartment__c, Province__c, Alias, Product_specialist_incharge_product__c, Use_Start_Date__c,' + ' ProfileId, Profile.Name, UserRoleId, UserRole.Name, Sales_Speciality__c, Post__c' + ' from User where IsActive = true and Test_staff__c = false'; /* if (String.isBlank(productUser) || productUser == '医院担当') { soql += ' and Sales_Speciality__c = \'医院担当\''; } else { soql += ' and Sales_Speciality__c <> \'医院担当\''; }*/ // 本部にて検索の場合、省を無視 if (searchByDpt) { loginUser.Province__c = null; // 省にて検索の場合、本部を無視 } else if (searchByProvince) { salesDpt = null; // 職位にて検索の場合 } else {} if (!String.isBlank(salesDpt)) { soql += ' and Salesdepartment__c = \'' + salesDpt + '\''; } if (!String.isBlank(loginUser.Province__c)) { soql += ' and Province__c = \'' + loginUser.Province__c + '\''; } /* if (String.isBlank(salesDpt) && String.isBlank(loginUser.Province__c)) { soql += ' and Salesdepartment__c = \'' + adminDpt + '\''; } if (searchByProvince) { salesDpt = adminDpt; }*/ soql += ' and Dept__c = \'能量事业本部\''; // 職位条件 List positionNames = new List(); for (Position p : plist) { if (p.check) { positionNames.add(p.positionName); } } if (positionNames.size() > 0) { soql += ' and ('; for (Integer i = 0; i < positionNames.size(); i++) { if (i == positionNames.size() - 1) { soql += ' Post__c = \'' + positionNames[i] + '\''; } else { soql += ' Post__c = \'' + positionNames[i] + '\' or'; } } soql += ')'; } soql += ' order by Salesdepartment__c, Province__c, UserRole.Name'; return Database.query(soql); } // 数据赋值 private void setBean(Integer year) { // 取得当前年度目标数据 //Opportunity[] opportunitys = ControllerUtil.oppSelectForPersonTaget(rt.Id, users, currentPeriod); // OLY_OCM-202 Opportunity[] opportunitys = [select Id, OwnerId, Opportunity_Category__c, Proportion__c, CloseDate, Amount, Objective__c, Target_category__c, SAP_Province__c, RecordTypeId, OCM_Target_period__c from Opportunity where Target_category__c = '担当目标' and RecordTypeId = :rt.Id and OwnerId in :users and OCM_Target_period__c = :currentPeriod]; // 当前年度没有数据时,显示信息 if (opportunitys.size() <= 0 && isPast && iYear < currentYear) { ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.INFO, '没有上年度的数据。'); ApexPages.addMessage(msg); previousRendered = false; iYear += 1; currentPeriod = String.valueOf(iYear - 1867 + 'P'); isPast = false; if (iYear < currentYear && !(currentYear - iYear == 1 && iMonth == 4 && iDay <= iBuffer)) { isPast = true; }// else if (iYear == currentYear) { // if (Date.today().month() == 3) { // isPast = true; // } // } // 今表示しているデータを再取得 setBean(iYear); return; } // 保存当前年度所有既存目标数据 oppMap = new Map(); for (Opportunity opp : opportunitys) { if (opp.OwnerId != null && opp.Opportunity_Category__c != null && opp.CloseDate !=null){ // 目标 key : OwnerId + _ + Opportunity_Category__c + _ + CloseDate(yyyy-mm-dd) String key = opp.OwnerId + '_' + opp.Opportunity_Category__c + '_' + String.valueOf(opp.CloseDate); oppMap.put(key, opp); } } // 建立数据集 dataBeans = new List(); for (Integer u = 0; u < users.size(); u++) { DataBean dataBean = new DataBean(users[u], oppMap, iYear); dataBeans.add(dataBean); } } // 実際の保存ロジック private void saveLogic() { List saveList = new List(); List deleteList = new List(); // 只处理当前本部数据 for (Integer d = 0; d < dataBeans.size(); d++) { DataBean db = dataBeans[d]; // 寄存数据比例值是否变化 Boolean proportionChanged = false; for (Integer i = 0; i < 12; i++) { Integer y = iYear; Integer m = 4 + i; if (m > 12) { y += 1; m -= 12; } String syear = String.valueOf(y); String smonth = String.valueOf(m); if (m < 10) { smonth = '0' + smonth; } String sTargetDay = syear + '-' + smonth + '-01'; // 按金额分类顺序处理 for (Integer j = 0; j < amountCategory.size(); j++) { String amountC = amountCategory[j]; // 数据检索Key String key = db.user.Id + '_' + amountC + '_' + sTargetDay; // 每月数据赋值 Opportunity opp = new Opportunity(); if (oppMap.containskey(key)) { opp = oppMap.get(key); if (opp.Proportion__c != proportion.get(amountC)[i]) { proportionChanged = true; break; } } } if (proportionChanged) { break; } } if (db.isChanged == '0' && !proportionChanged) { continue; } // 使用开始后目标金额补正系数计算 Map proportionSumMap = new Map(); for (Integer j = 0; j < amountCategory.size(); j++) { String amountC = amountCategory[j]; proportionSumMap.put(amountC, 0.0); } for (Integer i = 0; i < 12; i++) { Integer y = iYear; Integer m = 4 + i; if (m > 12) { y += 1; m -= 12; } String syear = String.valueOf(y); String smonth = String.valueOf(m); if (m < 10) { smonth = '0' + smonth; } String sTagetDay = syear + '-' + smonth + '-01'; Date tagetDay = Date.valueOf(sTagetDay); if (db.user.Use_Start_Date__c < tagetDay) { //proportionSum += proportion[i]; for (Integer j = 0; j < amountCategory.size(); j++) { String amountC = amountCategory[j]; proportionSumMap.put(amountC, proportionSumMap.get(amountC) + proportion.get(amountC)[i]); } } } //proportionSum = proportionSum / 100; for (Integer j = 0; j < amountCategory.size(); j++) { String amountC = amountCategory[j]; proportionSumMap.put(amountC, proportionSumMap.get(amountC) / 100); } // 一年分成12条数据 for (Integer i = 0; i < 12; i++) { Integer y = iYear; Integer m = 4 + i; if (m > 12) { y += 1; m -= 12; } String syear = String.valueOf(y); String smonth = String.valueOf(m); if (m < 10) { smonth = '0' + smonth; } String sTagetDay = syear + '-' + smonth + '-01'; Date tagetDay = Date.valueOf(sTagetDay); if (db.user.Use_Start_Date__c >= tagetDay) { // 使用開始当月 及び 開始前 は目標を登録しない,无视。 continue; } // 按金额分类顺序处理 for (Integer j = 0; j < amountCategory.size(); j++) { String amountC = amountCategory[j]; // 数据检索Key String key = db.user.Id + '_' + amountC + '_' + sTagetDay; // 每月数据赋值 Opportunity opp = new Opportunity(); if (oppMap.containskey(key)) { opp = oppMap.get(key); if (db.amount[j].Amount == null || db.amount[j].Amount == 0) { deleteList.add(opp); continue; } opp.Proportion__c = proportion.get(amountC)[i]; opp.Amount = db.amount[j].Amount / proportionSumMap.get(amountC); } else { if (db.amount[j].Amount == null || db.amount[j].Amount == 0) { continue; } opp.Name = db.user.Alias + ' 担当目标'; opp.StageName = '目標'; opp.OwnerId = db.user.Id; // トリガをスルーのため、ここでやります opp.Owner_System__c = db.user.Id; opp.Opportunity_Category__c = amountC; opp.Proportion__c = proportion.get(amountC)[i]; opp.CloseDate = tagetDay; opp.Amount = db.amount[j].Amount / proportionSumMap.get(amountC); opp.Target_category__c = '担当目标'; opp.SAP_Province__c = db.user.Province__c; opp.RecordTypeId = rt.Id; opp.OCM_Target_period__c = currentPeriod; } // 加入保存列表 saveList.add(opp); } } // 数据库限制小于10000条 if (saveList.size() + deleteList.size() >= 4000) { ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, '操作数据量过大,截止至' + db.user.Alias + '的数据操作完成,之后的数据请再次输入并保存。')); break; } } // トリガをスルー StaticParameter.EscapeOpportunityBefUpdTrigger = true; StaticParameter.EscapeOpportunityHpDeptUpdTrigger = true; StaticParameter.EscapeNFM007Trigger = true; // 更新数据库 if (saveList.size() > 0) upsert saveList; if (deleteList.size() > 0) delete deleteList; } // 数据类 class DataBean { // 担当者信息 public User user { get; private set; } // 总金额,画面用 public Opportunity[] amount { get; set; } // 是否变化 0:无 1:有 public String isChanged { get; set; } // 构造方法 DataBean(User user, Map oppMap, Integer iYear) { this.user = user; this.amount = new List(); this.isChanged = '0'; // 按金额分类,查找数据,并设值 for (Integer i = 0; i < amountCategory.size(); i++) { String amountC = amountCategory[i]; Opportunity a = new Opportunity(); a.Opportunity_Category__c = amountC; Decimal amountSum = 0.0; for (Integer j = 0; j < 12; j++) { Integer y = iYear; Integer m = 4 + j; if (m > 12) { y += 1; m -= 12; } String strY = String.valueOf(y); String strM = String.valueOf(m); if (strM.length() < 2) { strM = '0' + strM; } String key = user.Id + '_' + amountC + '_' + strY + '-' + strM + '-01'; if (oppMap.containskey(key)) { //a.Amount = oppMap.get(key).Amount; amountSum += oppMap.get(key).Objective__c == null ? 0 : oppMap.get(key).Objective__c; } } if (amountSum > 0) { amountSum = amountSum.setScale(2); a.Amount = amountSum; } this.amount.add(a); } } } // 職位チェックボックスリスト作成 class Position { public String positionName { get; private set; } public Boolean check { get; set; } public Position(String positionName, Boolean flg) { this.positionName = positionName; this.check = flg; } } }