/** * サビコン見積PDFのコントローラです。 */ public with sharing class MaintenanceContractEstimatePDFController { /** 処理対象の見積オブジェクトです。 */ public EstimateInfo targetObj { get; private set; } /** 見積オブジェクトのリスト(改ページ用) */ public List targetObjList { get; private set; } /** 1ページに表示する明細の数です。 */ private Integer rowSize = 13; // TODO ラベルに定義 private Integer nameMax = 23; private Integer commentMax = 5; private Integer lineNo = 0; public Integer year { get; private set; } public Integer getTargetObjSize() { return this.targetObjList.size(); } /** * Visualforceページがアクセスするコンストラクタです。 * 印刷するデータを収集し、インスタンス変数にセットします。 * @param controller スタンダードコントローラーのインスタンス */ public MaintenanceContractEstimatePDFController(ApexPages.StandardController controller) { } public void init() { String targetEstimateId = ApexPages.currentPage().getParameters().get('id'); // 見積情報を取得、必ずあるはず // TODO 書き方修正 List mceList = [SELECT Id, Name, Maintenance_Contract__c, Estimate_Target__c, Dealer__r.Name, CreatedDate, Maintenance_Contract__r.Management_Code__c, Maintenance_Contract__r.Hospital__r.Name, Department__c, Contract_Range__c, Contract_Esti_Start_Date__c, Contract_Esti_End_Date__c, Contract_Start_Date__c, Contract_End_Date__c, Estimate_Trial_Money__c, Asset_Repair_Sum_Price__c, Maintenance_Price__c, NotUse_Oxygenated_Water__c, Examination_Price__c, Service_contract_target_number__c, Append_Condition_Price__c, Discount_Price__c, Discount_Percentage__c, Last_Discount__c, Asset_Sum_Price__c, Print_Contract__c, Print_RepairPrice__c, Print_DiscountPercentage__c, Print_DiscountPrice__c, Print_ListPrice__c, Print_MaintePrice__c, Print_SumPrice__c FROM Maintenance_Contract_Estimate__c WHERE Id = :targetEstimateId] ; // 見積を取得できない場合 if (mceList.size() == 0) { throw new ControllerUtil.myException('报价不存在'); } this.targetObj = new EstimateInfo(mceList); targetObjList = new List(); // ページ毎に見積の情報(製品はページ毎にバラバラ) EstimateInfo tmpTargetObj = new EstimateInfo(mceList); // 新品と酸化水の金額を算出するため、製品を一リストに集約 EstimateInfo targetObjForSum = this.targetObj; // 合計の出力フラグによりページ毎の行数を変更 if (!this.targetObj.estimate.Print_SumPrice__c) { rowSize = rowSize + 3; } if (!this.targetObj.estimate.Print_MaintePrice__c) { rowSize = rowSize + 1; } // 明細の設定 Integer cnt = 1; for(Maintenance_Contract_Asset_Estimate__c mcae : [SELECT Id, Name, Asset__c, Asset__r.Name, Asset__r.SerialNumber, Asset__r.InstallDate, Product_Manual__c, Product_Manual__r.Maintenance_Price_Month__c, Product_Manual__r.Name, IsNew__c, Maintenance_Price_Month__c, Estimate_List_Price__c, Check_Result__c, Repair_Price__c, Comment__c FROM Maintenance_Contract_Asset_Estimate__c WHERE Maintenance_Contract_Estimate__c = :this.targetObj.estimate.Id ORDER BY Product_Manual__c, Asset__r.SerialNumber, Asset__r.Name, Asset__r.Department_Name__c, Asset__r.InstallDate]) { //for(Integer a=0;a<20;a++){ //tmpTargetObj.addAssetInfo(mcae); //targetObjForSum.addAssetInfo(mcae); String sname = ''; if (mcae.Asset__c != null) { sname = mcae.Asset__r.Name == null ? '' : mcae.Asset__r.Name; } else if (mcae.Product_Manual__c != null) { sname = mcae.Product_Manual__r.Name == null ? '' : mcae.Product_Manual__r.Name; } String smodelNo = ''; String scomment = mcae.Comment__c == null ? '' : mcae.Comment__c; if (sname.indexOf(':') >= 0) { smodelNo = sname.subString(0, sname.indexOf(':')+1); sname = sname.subString(sname.indexOf(':')+1); } else if (sname.indexOf(':') >= 0) { smodelNo = sname.subString(0, sname.indexOf(':')+1); sname = sname.subString(sname.indexOf(':')+1); } else { smodelNo = ''; } Integer iname = (sname.length() / nameMax) + (Math.mod(sname.length(), nameMax) > 0 ? 1 : 0); if (iname == 0) { iname = 1; } Integer icomment = (scomment.length() / commentMax) + (Math.mod(scomment.length(), commentMax) > 0 ? 1 : 0); if (icomment == 0) { icomment = 1; } Integer icnt = iname; if (iname < icomment) { icnt = icomment; } if (icnt > 1) { for (Integer i = 0; i < icnt; i++) { if (i == 0) { String printName = ''; if (i + 1 == iname) { printName = smodelNo + sname; } else { printName = smodelNo + sname.substring(0, nameMax); } if (i + 1 == icomment) { mcae.Comment__c = scomment; } else { mcae.Comment__c = scomment.substring(0, commentMax); } lineNo += 1; tmpTargetObj.addAssetInfo(lineNo, mcae, printName); targetObjForSum.addAssetInfo(lineNo, mcae, printName); } else { String printName = ''; Maintenance_Contract_Asset_Estimate__c newmcae = mcae.clone(); if (i < iname) { if (i + 1 == iname) { printName = sname.substring(i*nameMax); } else { printName = sname.substring(i*nameMax, (i+1)*nameMax); } } else { printName = ''; } if (i < icomment) { if (i + 1 == icomment) { newmcae.Comment__c = scomment.substring(i*commentMax); } else { newmcae.Comment__c = scomment.substring(i*commentMax, (i+1)*commentMax); } } else { newmcae.Comment__c = ''; } tmpTargetObj.addAssetInfo(lineNo, newmcae, printName); targetObjForSum.addAssetInfo(lineNo, newmcae, printName); AssetInfo ainfo = tmpTargetObj.assetInfoList.get(tmpTargetObj.assetInfoList.size()-1); ainfo.lineNo = null; ainfo.assetModelNo = null; ainfo.assetSerialNumber = null; ainfo.installDate = null; ainfo.mcae.Check_Result__c = null; ainfo.listPrice = 0.0; ainfo.repairPrice = 0.0; ainfo.newDiscount = 0.0; ainfo.quantity = null; ainfo.mcae.Repair_Price__c = null; ainfo.mcae.Estimate_List_Price__c = null; AssetInfo ainfo2 = targetObjForSum.assetInfoList.get(targetObjForSum.assetInfoList.size()-1); ainfo2.lineNo = null; ainfo2.assetModelNo = null; ainfo2.assetSerialNumber = null; ainfo2.installDate = null; ainfo2.mcae.Check_Result__c = null; ainfo2.listPrice = 0.0; ainfo2.repairPrice = 0.0; ainfo2.newDiscount = 0.0; ainfo2.quantity = null; ainfo2.mcae.Repair_Price__c = null; ainfo2.mcae.Estimate_List_Price__c = null; } // 改ページ判断 if (cnt == this.rowSize) { cnt = 0; targetObjList.add(tmpTargetObj); tmpTargetObj = new EstimateInfo(mceList); } cnt++; } } else { lineNo += 1; tmpTargetObj.addAssetInfo(lineNo, mcae, null); targetObjForSum.addAssetInfo(lineNo, mcae, null); // 改ページ判断 if (cnt == this.rowSize) { cnt = 0; targetObjList.add(tmpTargetObj); tmpTargetObj = new EstimateInfo(mceList); } cnt++; } // } } // 新品优惠 lineNo += 1; Boolean rs = tmpTargetObj.addNewDiscountLine(lineNo, targetObjForSum.assetInfoList); targetObjForSum.addNewDiscountLine(lineNo, targetObjForSum.assetInfoList); if (!rs) { lineNo -= 1; } // xudan 20140424 バグ修正、ちょうど改ページ後の第一行目に、新品优惠を出すかどうかの判断を修正 if (tmpTargetObj.assetInfoList.size() > 0 && tmpTargetObj.assetInfoList[tmpTargetObj.assetInfoList.size() - 1].assetName == '新品优惠') { if (cnt == this.rowSize) { cnt = 0; targetObjList.add(tmpTargetObj); tmpTargetObj = new EstimateInfo(mceList); } cnt++; } // 酸化水非使用 if (tmpTargetObj.estimate.NotUse_Oxygenated_Water__c) { lineNo += 1; tmpTargetObj.addOxyDiscount(lineNo, targetObjForSum.assetInfoList); targetObjForSum.addOxyDiscount(lineNo, targetObjForSum.assetInfoList); if (cnt == this.rowSize) { cnt = 0; targetObjList.add(tmpTargetObj); tmpTargetObj = new EstimateInfo(mceList); } cnt++; } // 遡るIdx、端数処理金額をどんなページに置くかを制御 Integer backIdx = this.calcBackIdx(cnt); // 遡るIdx、端数処理金額をどんな行に置くかを制御 Integer backDetailIdx = this.calcBackDetailIdx(cnt); // 定期点検 lineNo += 1; tmpTargetObj.addExaminationPrice(lineNo, tmpTargetObj.estimate); targetObjForSum.addExaminationPrice(lineNo, tmpTargetObj.estimate); targetObjList.add(tmpTargetObj); // 会計年度計算、ただしここは 日本の年度ではない // Integer y = this.targetObj.estimate.Contract_Esti_Start_Date__c.year(); // Integer m = this.targetObj.estimate.Contract_Esti_Start_Date__c.month(); Integer y = this.targetObj.estimate.Contract_Start_Date__c.year(); Integer m = this.targetObj.estimate.Contract_Start_Date__c.month(); if (m >= 4) { this.year = y; } else { this.year = y; // y - 1; } // 合計金額との端数処理の場合、修理金額を無視 // 実際金額との端数処理の場合、修理金額を含む(実際=合計+修理-优惠) Boolean countRepair = false; Decimal finalPrice = 0; // listpriceと実際金額の差額対応,端数処理 if (!this.targetObj.estimate.Print_SumPrice__c && this.targetObj.estimate.Print_MaintePrice__c) { //this.targetObj.estimate.Examination_Price__c = (this.targetObj.estimate.Examination_Price__c * (1 - this.targetObj.estimate.Discount_Percentage__c / 100)).setScale(2, RoundingMode.HALF_UP); // listpriceと実際金額の差額対応 // finalPrice = this.targetObj.estimate.Maintenance_Price__c - this.targetObj.estimate.Examination_Price__c; finalPrice = this.targetObj.estimate.Maintenance_Price__c; countRepair = true; } // listpriceと合計金額の差額対応,端数処理 else { // finalPrice = this.targetObj.estimate.Estimate_Trial_Money__c - this.targetObj.estimate.Examination_Price__c; finalPrice = this.targetObj.estimate.Estimate_Trial_Money__c; } Decimal tmpPrice = 0; for (Integer i = 0; i < targetObjForSum.assetInfoList.size(); i++) { tmpPrice += targetObjForSum.assetInfoList[i].listPrice != null ? targetObjForSum.assetInfoList[i].listPrice : 0; if (countRepair) { if (targetObjForSum.assetInfoList[i].repairPrice != null) { tmpPrice += targetObjForSum.assetInfoList[i].repairPrice; } } system.debug('tmpPrice:::' + tmpPrice); } system.debug('finalPrice:::' + finalPrice); system.debug('targetObjList.size():::' + targetObjList.size()); system.debug('backIdx:::' + backIdx); system.debug('backDetailIdx:::' + backDetailIdx); if (finalPrice - tmpPrice != 0) { // targetObjList.size()=ページ数 if (targetObjList.size() - 1 - backIdx >= 0) { // assetSize=ページ内の明細行数 Integer assetSize = targetObjList[targetObjList.size() - 1 - backIdx].assetInfoList.size(); if (assetSize - 1 - backDetailIdx >= 0) { targetObjList[targetObjList.size() - 1 - backIdx].assetInfoList[assetSize - 1 - backDetailIdx].listPrice += finalPrice - tmpPrice; } } } } /** * 遡るIdx計算 */ private Integer calcBackIdx(Integer cnt) { // 定期点検行の前ちょうどに改ページ if (cnt == 1) { // 最後ページは明細がない、誤差補正金額を前ページの明細に加算 return 1; } else { // 最後ページは明細があり、誤差補正金額をこのページの明細に加算 return 0; } } /** * 遡るIdx計算 */ private Integer calcBackDetailIdx(Integer cnt) { // 定期点検行の前ちょうどに改ページ if (cnt == 1) { // 最後ページは定期点検しかない、誤差補正金額を前ページの最後行に加算 return 0; } else { // 最後ページは明細があり、誤差補正金額をこのページの定期点検行の上に加算 return 1; } } /** * 印刷するデータを格納するオブジェクを定義する、親 */ public class EstimateInfo { public Maintenance_Contract_Estimate__c estimate {get; private set;} public String createdDate {get; private set;} public List assetInfoList {get; private set;} public EstimateInfo(List estimateList) { if (estimateList.size() > 0) { this.estimate = estimateList[0]; this.createdDate = estimateList[0].CreatedDate.format('yyyy/MM/dd'); this.assetInfoList = new List(); } } public void addAssetInfo(Integer lno, Maintenance_Contract_Asset_Estimate__c mcae, String printName) { this.assetInfoList.add(new AssetInfo(lno, mcae, estimate, printName)); } public Boolean addNewDiscountLine(Integer lno, List tmpAssetInfoList) { AssetInfo tmpNewDiscount = new AssetInfo(lno); tmpNewDiscount.assetModelNo = '新品优惠'; tmpNewDiscount.assetName = '新品优惠'; tmpNewDiscount.assetSerialNumber = '-'; tmpNewDiscount.installDate = '-'; tmpNewDiscount.quantity = null; for (AssetInfo ai : tmpAssetInfoList) { tmpNewDiscount.listPrice -= ai.newDiscount; } if (tmpNewDiscount.listPrice < 0) { assetInfoList.add(tmpNewDiscount); return true; } return false; } public void addOxyDiscount(Integer lno, List tmpAssetInfoList) { AssetInfo tmpOxyDiscount = new AssetInfo(lno); tmpOxyDiscount.assetModelNo = '酸化水'; tmpOxyDiscount.assetName = '酸化水'; tmpOxyDiscount.assetSerialNumber = '-'; tmpOxyDiscount.installDate = '-'; tmpOxyDiscount.quantity = null; Decimal tmpPrice = 0; // 消毒液折扣=(定价-新品折扣)*0.1 for (AssetInfo ai : tmpAssetInfoList) { // 新品优惠を追加した場合、新品优惠行をスキップ if (ai.assetName != '新品优惠') { system.debug(ai.listPrice); system.debug(ai.newDiscount); tmpPrice += ai.listPrice - ai.newDiscount; system.debug(tmpPrice); } } tmpOxyDiscount.listPrice -= tmpPrice * 0.1; assetInfoList.add(tmpOxyDiscount); } public void addExaminationPrice(Integer lno, Maintenance_Contract_Estimate__c mce) { AssetInfo tmpCheckPrice = new AssetInfo(lno); tmpCheckPrice.assetModelNo = '定期点检'; tmpCheckPrice.assetName = '定期点检'; tmpCheckPrice.assetSerialNumber = '-'; tmpCheckPrice.installDate = '-'; tmpCheckPrice.quantity = Integer.valueOf(mce.Service_contract_target_number__c); tmpCheckPrice.listPrice = null; // tmpCheckPrice.listPrice = mce.Examination_Price__c; // if (!mce.Print_SumPrice__c && mce.Print_MaintePrice__c) { // tmpCheckPrice.listPrice = (mce.Examination_Price__c * (1 - mce.Discount_Percentage__c / 100)).setScale(2, RoundingMode.HALF_UP); // } assetInfoList.add(tmpCheckPrice); } } /** * 印刷するデータを格納するオブジェクを定義する、子供 */ public class AssetInfo { public Integer lineNo {get; private set;} public Maintenance_Contract_Asset_Estimate__c mcae {get; private set;} public Decimal listPrice {get; private set;} public Decimal repairPrice {get; private set;} public Decimal newDiscount {get; private set;} public String assetModelNo {get; private set;} public String assetName {get; private set;} public String assetSerialNumber {get; private set;} public Integer quantity {get; private set;} public String installDate {get; private set;} public AssetInfo(Integer lineNo) { this.lineNo = lineNo; this.listPrice = 0.0; this.repairPrice = 0.0; this.newDiscount = 0.0; this.mcae = null; } public AssetInfo(Integer lineNo, Maintenance_Contract_Asset_Estimate__c mcae, Maintenance_Contract_Estimate__c estimate, String printName) { this.lineNo = lineNo; this.mcae = mcae; this.listPrice = 0.0; this.newDiscount = 0.0; this.repairPrice = 0.0; this.quantity = 1; Decimal month = estimate.Contract_Range__c; if (month > 12) { month = 12; } if (mcae.Asset__c != null) { // Assetある if (printName == null) { this.assetName = mcae.Asset__r.Name; } else { this.assetName = printName; } this.assetSerialNumber = mcae.Asset__r.SerialNumber; this.listPrice = estimate.Contract_Range__c * mcae.Estimate_List_Price__c; this.installDate = mcae.Asset__r.InstallDate != null ? String.valueOf(mcae.Asset__r.InstallDate).replace('-', '/') : ''; if (mcae.IsNew__c) { this.listPrice = estimate.Contract_Range__c * mcae.Maintenance_Price_Month__c; // this.newDiscount = estimate.Contract_Range__c * (mcae.Maintenance_Price_Month__c - mcae.Estimate_List_Price__c); this.newDiscount = month * (mcae.Maintenance_Price_Month__c - mcae.Estimate_List_Price__c); } } else if (mcae.Product_Manual__c != null) { // 手入力 if (printName == null) { this.assetName = mcae.Product_Manual__r.Name; } else { this.assetName = printName; } this.assetSerialNumber = '新购入'; this.installDate = '新购入'; this.listPrice = estimate.Contract_Range__c * mcae.Product_Manual__r.Maintenance_Price_Month__c; // this.newDiscount = estimate.Contract_Range__c * (mcae.Product_Manual__r.Maintenance_Price_Month__c - mcae.Estimate_List_Price__c); this.newDiscount = month * (mcae.Product_Manual__r.Maintenance_Price_Month__c - mcae.Estimate_List_Price__c); } else {} if (mcae.Repair_Price__c != null) { this.repairPrice = mcae.Repair_Price__c; } // 合計金額出さずに実際金額を出す場合、値引きで表示、四捨五入 if (!estimate.Print_SumPrice__c && estimate.Print_MaintePrice__c) { this.listPrice = (this.listPrice * (1 - estimate.Discount_Percentage__c / 100)).setScale(2, RoundingMode.HALF_UP); this.newDiscount = (this.newDiscount * (1 - estimate.Discount_Percentage__c / 100)).setScale(2, RoundingMode.HALF_UP); } // 名前 ':' の対応 this.assetName = assetName == null ? '' : assetName; if (this.assetName.indexOf(':') >= 0) { this.assetModelNo = this.assetName.subString(0, this.assetName.indexOf(':')); this.assetName = this.assetName.subString(this.assetName.indexOf(':')+1); } else if (this.assetName.indexOf(':') >= 0) { this.assetModelNo = this.assetName.subString(0, this.assetName.indexOf(':')); this.assetName = this.assetName.subString(this.assetName.indexOf(':')+1); } else { this.assetModelNo = ''; } } } }