//Consum_Apply_Equipment_Set__c トリガHandler
// ConsumApplyEquipmentSetDetailHandlerTest
// ConsumApplyEquipmentSetHandlerTest
public without sharing class ConsumApplyEquipmentSetHandler extends Oly_TriggerHandler {
private Map newMap;
private Map oldMap;
private List newList;
private List oldList;
public ConsumApplyEquipmentSetHandler() {
if (Trigger.isUpdate || Trigger.isUndelete || Trigger.isDelete) {
this.newMap = new Map();
this.newList = new List();
this.oldMap = (Map) Trigger.oldMap; // old そのまま利用
this.oldList = (List) Trigger.old; // old そのまま利用
// 大前提 Fixture_Set__c ですが下記の属性が設定されています
// 参照関係に含まれる参照レコードは削除できません。
if (Trigger.isUpdate || Trigger.isUndelete) {
for (SObject nSObj : Trigger.new) {
Consum_Apply_Equipment_Set__c nObj = (Consum_Apply_Equipment_Set__c) nSObj;
Consum_Apply_Equipment_Set__c oObj = null;
if (Trigger.isUpdate) {
oObj = oldMap.get(nObj.Id);
}
if (Trigger.isUndelete == false) {
this.newList.add(nObj);
this.newMap.put(nObj.Id, nObj);
}
}
}
}
else {
// insert
this.newMap = (Map) Trigger.newMap;
this.oldMap = (Map) Trigger.oldMap;
this.newList = (List) Trigger.new;
this.oldList = (List) Trigger.old;
}
}
protected override void beforeInsert() {
beforeSetValue();
}
protected override void beforeUpdate() {
beforeSetValue();
}
protected override void afterInsert() {
Set raesIdSet = new Set();
formulaToTextCheck();
for (Consum_Apply_Equipment_Set__c nObj : newList) {
if (
//nObj.Min_Final_reply_day_Text__c != nObj.Min_Final_reply_day_F__c ||
nObj.Received_Confirm_Status_Text__c != nObj.Received_Confirm_Status_F__c) {
raesIdSet.add(nObj.Id);
}
}
// Batch では@future実行できません
if (raesIdSet.size() > 0 && !System.isBatch()) {
// before 数式の値がnullになる可能性がありますのでここでも一回チェックします
formulaToTextCheck(raesIdSet);
}
}
protected override void afterUpdate() {
// キャンセルコピー コピーを先にやらにとcancelフラグが全部falseに変更しますので
// cancelCopy();
Map raesdCMap = new Map();
Map raesdNGMap = new Map();
Set raesIdSet = new Set();
for (Consum_Apply_Equipment_Set__c nObj : newList) {
Consum_Apply_Equipment_Set__c oObj = oldMap.get(nObj.Id);
if (oObj.Cancel_Select__c == false && nObj.Cancel_Select__c == true) {
raesdCMap.put(nObj.Id, nObj);
}
//申请者收货NG变更到不是NG或申请者不是NG到NG的时候需要更新对应的明细(为了修改姓名)
if ((oObj.Received_Confirm__c != 'NG' && nObj.Received_Confirm__c == 'NG')
|| (oObj.Received_Confirm__c == 'NG' && nObj.Received_Confirm__c != 'NG')) {
raesdNGMap.put(nObj.Id, nObj);
}
if (
//nObj.Min_Final_reply_day_Text__c != nObj.Min_Final_reply_day_F__c ||
nObj.Received_Confirm_Status_Text__c != nObj.Received_Confirm_Status_F__c) {
raesIdSet.add(nObj.Id);
}
}
recCancelNGDetail(raesdCMap, raesdNGMap, true);
// before では数式項目がnullの場合があります
formulaToTextCheck();
// OLY_OCM-530: 一览从申请单A分到申请单B时,会检查A下是否有至少一条一览,如果没有则报错
checkOldApplyNotNull();
// Batch では@future実行できません
if (raesIdSet.size() > 0 && !System.isBatch()) {
// before 数式の値がnullになる可能性がありますのでここでも一回チェックします
formulaToTextCheck(raesIdSet);
}
}
// before 数式の値がnullになる可能性がありますのでここでも一回チェックします
@future
private static void formulaToTextCheck(Set raesdIdSet) {
List raesList = [SELECT Id
//, Min_Final_reply_day_Text__c
//, Min_Final_reply_day_F__c
, Received_Confirm_Status_Text__c
, Received_Confirm_Status_F__c
FROM Consum_Apply_Equipment_Set__c
WHERE Id = :raesdIdSet];
List updateRaesList = new List();
for (Consum_Apply_Equipment_Set__c raes : raesList) {
if (
//raes.Min_Final_reply_day_Text__c != raes.Min_Final_reply_day_F__c ||
raes.Received_Confirm_Status_Text__c != raes.Received_Confirm_Status_F__c) {
//raes.Min_Final_reply_day_Text__c = raes.Min_Final_reply_day_F__c;
raes.Received_Confirm_Status_Text__c = raes.Received_Confirm_Status_F__c;
updateRaesList.add(raes);
}
}
if (updateRaesList.size() > 0) {
update updateRaesList;
}
}
protected override void afterDelete() {
deleteEquipmentError(); // OLY_OCM-530: 如果是非"草案中"状态,删除一览则报错
}
// OLY_OCM-530: 新分的申请单名后缀num是根据一览的Old_Consum_Apply___c条数判断的,如果分出的申请单下一览是null,那么计算num时,这条分单就被忽略了。
// ---> 所以需要保证每个申请单下至少有一个一览(一览从申请单A分到申请单B时,会检查A下是否有至少一条一览,如果没有则报错)
private void checkOldApplyNotNull() {
Set oRaIds = new Set(); // 原申请单s
Consum_Apply_Equipment_Set__c nObj = null;
List oRaesList = new List();
for (Consum_Apply_Equipment_Set__c oObj : this.oldList) {
nObj = this.newMap.get(oObj.Id);
if(oObj.Consum_Apply__c != nObj.Consum_Apply__c && oObj.Consum_Apply__c != null) {
oRaIds.add(oObj.Consum_Apply__c);
oRaesList.add(oObj);
}
}
if (oRaIds.size() != 0) {
Set emptyRaObjs = checkConsumApplyNotExistRAES(oRaesList, oRaIds); // oldRaesList分单(转移)到新申请单后,没有一览的原申请单
if (emptyRaObjs.size() != 0) {
List raNameList = [
Select Id, Name
From Consum_Apply__c
Where Id in :emptyRaObjs];
Map raNameMap = new Map();
for (Consum_Apply__c ra : raNameList) {
raNameMap.put(ra.Id, ra.Name);
}
for (Consum_Apply_Equipment_Set__c oObj : oRaesList) {
if (emptyRaObjs.contains(oObj.Consum_Apply__c)) {
nObj = this.newMap.get(oObj.Id);
nObj.addError('申请单 ' + raNameMap.get(oObj.Consum_Apply__c) + ', 下一览不能为空');
}
}
}
}
}
/**
* @param oldRaesList 分单(转移)前的一览List
* @param raIds 原申请单
* @return 返回oldRaesList分单(转移)到新申请单后,没有一览的原申请单
*/
public static Set checkConsumApplyNotExistRAES(List oldRaesList, Set raIds) {
Set emptyRaIds = new Set(); // emptyRaIds--一览为空的申请单
Set oIds = new Set();
for (Consum_Apply_Equipment_Set__c oObj : oldRaesList) {
if (oObj.Id != null && false == oIds.contains(oObj.Id)) {
oIds.add(oObj.Id);
}
}
AggregateResult[] leftRaesRA = [ // (原申请单s中除了原一览s的一览)存在的申请单
Select Consum_Apply__c
From Consum_Apply_Equipment_Set__c
Where Id Not In :oIds
AND Consum_Apply__c In :raIds
group by Consum_Apply__c];
if (leftRaesRA.size() == 0) {
return raIds;
} else {
Set notERaIds = new Set();
for (AggregateResult ar : leftRaesRA) {
notERaIds.add(ar.get('Consum_Apply__c').toString());
}
for (String idObj : raIds) {
if (false == notERaIds.contains(idObj)) {
emptyRaIds.add(idObj);
}
}
}
return emptyRaIds;
}
// OLY_OCM-530: 如果是非"草案中"状态,删除一览则报错
private void deleteEquipmentError() {
for (Consum_Apply_Equipment_Set__c oObj : oldList) {
if (oObj.RAES_Status__c != FixtureUtil.raStatusMap.get(FixtureUtil.RaStatus.Cao_An_Zhong.ordinal())) {
oObj.addError('非草案中状态的一览不能删除');
}
}
}
private void beforeSetValue() {
// List raesIdList = new List();
Set fisSet = new Set();
for (Consum_Apply_Equipment_Set__c nObj : newList) {
// raesIdList.add(nObj.Id);
//if (String.isNotBlank(nObj.Fixture_Set__c)) {
// fisSet.add(nObj.Fixture_Set__c);
//}
}
// Map raesMap = new Map([
// SELECT Id, Fixture_Set__r.Name
// FROM Consum_Apply_Equipment_Set__c
// where Id in :raesIdList]);
//Map fdMap = new Map();
//if (fisSet.size() > 0) {
// fdMap = new Map([
// SELECT Id, Name
// FROM Fixture_Set__c
// where Id in :fisSet]);
//}
User applyUser = null; // 申請中になったとき、ログインユーザーからプレセス用の上司を設定
for (Consum_Apply_Equipment_Set__c nObj : newList) {
// raesIdList.add(nObj.Id);
Consum_Apply_Equipment_Set__c oObj = null;
if (Trigger.isUpdate) {
oObj = oldMap.get(nObj.Id);
//if (oObj.Received_Confirm__c != nObj.Received_Confirm__c) {
//if (nObj.Received_Confirm__c == null) {
// nObj.Loaner_received_time__c = null;
//} else {
// nObj.Loaner_received_time__c = Datetime.now();
//}
//}
}
if (nObj.Cancel_Select__c == false
&& nObj.RetalFSetDetail_Cnt__c == 0
&& nObj.RetalFSetDetail_Cancel_Cnt__c > 0) {
nObj.Cancel_Select__c = true;
nObj.Cancel_Reason__c = '明细汇总';
}
nObj.Loaner_centre_mail_address__c = nObj.Loaner_centre_mail_address_F__c;
if (nObj.Asset_return_time__c == null) {
nObj.Asset_return_time__c = nObj.Return_Time_New__c;
}
nObj.Received_Confirm_Text__c = nObj.Received_Confirm__c;
//Fixture_Set__c fs;
//if (fdMap.containsKey(nObj.Fixture_Set__c)) {
// fs = fdMap.get(nObj.Fixture_Set__c);
//}
//画面显示用clone出来的数据不需要设置Name
if (nObj.DataMigration_Flag__c == false
// 因为耗材没有备品配套,一览也不需要IndexFromUniqueKey__c所以注释
//&& String.isNotBlank(nObj.Fixture_Set__c)
//&& fs != null
//&& nObj.IndexFromUniqueKey__c != null
) {
String split_ApplyNum = nObj.RequestNoJoinStr2__c;
if (nObj.Consum_Apply_r_Name__c.contains('_')) {
// XXXX-YYYY_1 (ZZZZ_1)
List split_ApplyNumList = nObj.Consum_Apply_r_Name__c.split('_');
String raName = split_ApplyNumList[split_ApplyNumList.size() - 2]; // XXXX-YYYY (ZZZZ)
split_ApplyNum = split_ApplyNumList[split_ApplyNumList.size() - 1]; // 1
split_ApplyNumList = raName.split('-'); // [XXXX, YYYY] ([ZZZZ])
if (split_ApplyNumList.size() > 1) {
// YYYY_1
split_ApplyNum = split_ApplyNumList[split_ApplyNumList.size() - 1] + '_' + split_ApplyNum;
} else {
// ZZZZ_1
split_ApplyNum = nObj.Consum_Apply_r_Name__c;
}
}
nObj.Name = split_ApplyNum + ':' + nObj.Model_No__c;
// 如果是分配代替品名字加:Sub
//if (nObj.Substitute_Select_Again__c) {
// nObj.Name += ':Sub';
//}
//一览时申请者收货NG的话名字添加NG
if (nObj.NG_Select_Again__c) {
nObj.Name += ':NG';
}
//取消的时候名字加Canceled
if (nObj.Cancel_Select__c) {
nObj.Name += ':Canceled';
}
}
if (nObj.DataMigration_Flag__c == false && (!Trigger.isUpdate || String.isNotBlank(nObj.Model_No__c))) {
nObj.UniqueKey__c = nObj.RequestNoJoinStr2__c + ':'+ nObj.Model_No__c + ':'+ nObj.IndexFromUniqueKey__c;
if (nObj.Cancel_Select__c
//|| nObj.Substitute_Select_Again__c
|| nObj.NG_Select_Again__c
) {
nObj.UniqueKey__c += nObj.Id;
}
}
// 取消分配
if (Trigger.isInsert || oObj.Cancel_Select__c != nObj.Cancel_Select__c) {
if (nObj.Cancel_Select__c && nObj.NG_Select_Again__C == false) {
nObj.Cancel_Date__c = System.today();
nObj.Cancel_Time__c = MainFixtureSelectController.getCurrentTime();
nObj.Cancel_Mem__c = UserInfo.getUserId();
nObj.Consum_Start_Date__c = null;
//nObj.Consum_End_Date__c = null;
// 使用入力规则
//if (String.isBlank(nObj.Cancel_Reason__c)) {
// nObj.Cancel_Reason__c.addError('必须输入取消理由。');
//}
} else {
nObj.Cancel_Date__c = null;
nObj.Cancel_Time__c = null;
nObj.Cancel_Mem__c = null;
nObj.Cancel_Reason__c = null;
// TODO 取消理由备注 确认
if (String.isNotBlank(nObj.Loaner_cancel_Remarks__c)) {
nObj.Loaner_cancel_Remarks__c = null;
}
}
}
// liucheng 20171112
// 配套备品型号(借出时)
//if (String.isBlank(nObj.Loaner_code_text__c)) {
// nObj.Loaner_code_text__c = nObj.Loaner_code__c;
//}
// 配套备品名称(借出时)
//if (String.isBlank(nObj.Loaner_name_text__c)) {
// nObj.Loaner_name_text__c = nObj.Loaner_name__c;
//}
//if (String.isBlank(nObj.Equipment_Set_Borrowed__c) && fs != null) {
// // 备品set(借出时)
// nObj.Equipment_Set_Borrowed__c = fs.Name;
//}
//bp2 OLY_OCM-85 通过 EquipmentSetDailyBatch 会自动延期,4个审批流程不需要了
// 所以不需要了
// // ----------------------------------------------------------------------
// // ここより、承認プロセス用に、经理、部长、总监を更新する
// // ----------------------------------------------------------------------
// // 申請中かどうかのチェック
// if ( ( Trigger.isInsert || oObj.Extend_Status__c != nObj.Extend_Status__c)
// && nObj.Extend_Status__c == '申请中') {
// if (applyUser == null) {
// applyUser = [SELECT Id, Name, SalesManager__c, BuchangApprovalManagerSales__c, JingliApprovalManager__c, BuchangApprovalManager__c, ZongjianApprovalManager__c FROM User WHERE Id = :nObj.applyUser__c];
// }
// nObj.SalesManager__c = applyUser.SalesManager__c == null
// ? applyUser.Id : applyUser.SalesManager__c;
// nObj.BuchangApprovalManagerSales__c = applyUser.BuchangApprovalManagerSales__c == null
// ? applyUser.Id : applyUser.BuchangApprovalManagerSales__c;
// nObj.JingliApprovalManager__c = applyUser.JingliApprovalManager__c == null
// ? applyUser.Id : applyUser.JingliApprovalManager__c;
// nObj.BuchangApprovalManager__c = applyUser.BuchangApprovalManager__c == null
// ? applyUser.Id : applyUser.BuchangApprovalManager__c;
// nObj.ZongjianApprovalManager__c = applyUser.ZongjianApprovalManager__c == null
// ? applyUser.Id : applyUser.ZongjianApprovalManager__c;
// }
// // ----------------------------------------------------------------------
// // ここまで、承認プロセス用に、经理、总监を更新する
// // ----------------------------------------------------------------------
// 必ず最後で置く
nObj.Received_Confirm_Status_Text__c = nObj.Received_Confirm_Status_F__c;
nObj.Canceled_Id__c = nObj.Canceled__c;
//nObj.Substitute_flag__c = nObj.Substitute_Select_Again__c;
//nObj.NG_Final_reply_day_Text__c = nObj.NG_Final_reply_day_F__c;
//nObj.Yizhouweixiu_Final_reply_day_Text__c = nObj.Yizhouweixiu_Final_reply_day_F__c;
//nObj.Extend_Final_reply_day_Text__c = nObj.Extend_Final_reply_day_F__c;
//nObj.QIS_Final_reply_day_Text__c = nObj.QIS_Final_reply_day_F__c;
//nObj.Repair_cancel_Final_reply_day_Text__c = nObj.Repair_cancel_Final_reply_day_F__c;
//nObj.Return_to_office_Final_reply_day_Text__c = nObj.Return_to_office_Final_reply_day_F__c;
//nObj.Repair_delete_Final_reply_day_Text__c = nObj.Repair_delete_Final_reply_day_F__c;
//nObj.Yigoudaihuo_Final_reply_day_Text__c = nObj.Yigoudaihuo_Final_reply_day_F__c;
nObj.Repair_Agreed_Quotation_Text__c = nObj.Repair_Agreed_Quotation_F__c;
/*
Min_Final_reply_day_F__c =
MIN(
NG_Final_reply_day_Text__c
Yizhouweixiu_Final_reply_day_Text__c
Extend_Final_reply_day_Text__c
QIS_Final_reply_day_Text__c
Repair_cancel_Final_reply_day_Text__c
Return_to_office_Final_reply_day_Text__c
Repair_delete_Final_reply_day_Text__c
Yigoudaihuo_Final_reply_day_Text__c
)
Min_Final_reply_day_Text__cの設定は最後にする必要があります
*/
//nObj.Min_Final_reply_day_Text__c = nObj.Min_Final_reply_day_F__c;
// nObj.Final_reply_day2__c = nObj.Final_reply_day__c;
}
}
//明細更新メソッド(Batch 专用) 更新明細:一覧Cancel明細もCancel
// 一覧申请者收获NG明細更新Name
// 必須項目:Cancel_Reason__c, Loaner_cancel_Remarks__c
// @param raesdCMap Cancel一覧Map
// @param raesdNGMap 申请者NG変更一覧Map
// @return 保存结果
public static Database.SaveResult[] recCancelNGDetailBatch(Map raesdCMap, Map raesdNGMap) {
return recCancelNGDetail(raesdCMap, raesdNGMap, false);
}
//明細更新メソッド 更新明細:一覧Cancel明細もCancel
// 一覧申请者收获NG明細更新Name
// 必須項目:Cancel_Reason__c, Loaner_cancel_Remarks__c
// @param raesdCMap Cancel一覧Map
// @param raesdNGMap 申请者NG変更一覧Map
// @param allOrNone 不允许部分保存
// @return 保存结果
private static Database.SaveResult[] recCancelNGDetail(Map raesdCMap, Map raesdNGMap, Boolean allOrNone) {
// null.isEmpty の場合えラー
if (raesdCMap == null) {
raesdCMap = new Map();
}
// null.isEmpty の場合えラー
if (raesdNGMap == null) {
raesdNGMap = new Map();
}
//更新明细
Map raesdMap = new Map();
//取消更新的明细
if (!raesdCMap.isEmpty()) {
List raesds = [
Select Id
, Consum_Apply_Equipment_Set__c
//, Is_Body__c
From Consum_Apply_Equipment_Set_Detail__c
Where Consum_Apply_Equipment_Set__c = :raesdCMap.keySet()
AND Cancel_Select__c = false
AND DeliverySlip__c = null];
for (Consum_Apply_Equipment_Set_Detail__c raesd :raesds) {
raesd.Cancel_Select__c = true;
raesd.Cancel_Mem__c = UserInfo.getUserId();
raesd.Cancel_Date__c = Date.today();
raesd.Cancel_Time__c = MainFixtureSelectController.getCurrentTime();
raesd.Cancel_Reason__c = raesdCMap.get(raesd.Consum_Apply_Equipment_Set__c).Cancel_Reason__c;
raesd.Loaner_cancel_Remarks__c = raesdCMap.get(raesd.Consum_Apply_Equipment_Set__c).Loaner_cancel_Remarks__c;
raesdMap.put(raesd.Id, raesd);
}
}
//申请者收货NG的明细
if (!raesdNGMap.isEmpty()) {
List raesds = [
Select Id, Consum_Apply_Equipment_Set__c
From Consum_Apply_Equipment_Set_Detail__c
Where Consum_Apply_Equipment_Set__c = :raesdNGMap.keySet()];
for (Consum_Apply_Equipment_Set_Detail__c raesd :raesds) {
if (!raesdMap.containsKey(raesd.Id)) {
raesdMap.put(raesd.Id, raesd);
}
}
}
if (!raesdMap.isEmpty()) {
return Database.update(raesdMap.values(), allOrNone);
}
return null;
}
// private void cancelCopy() {
// Map raesdMap = new Map();
// for (Consum_Apply_Equipment_Set__c nObj : newList) {
// Consum_Apply_Equipment_Set__c oObj = oldMap.get(nObj.Id);
// if (nObj.Ra_Cancel_Select__c == false
// && (oObj.Cancel_Select__c == false && nObj.Cancel_Select__c == true)) {
// Consum_Apply_Equipment_Set__c nraescolone = new Consum_Apply_Equipment_Set__c();
// nraescolone.Consum_Apply__c = nObj.Consum_Apply__c;
// nraescolone.Fixture_Set__c = nObj.Fixture_Set__c;
// nraescolone.Canceled_Id__c = nObj.Id;
// raesdMap.put(nObj.Id, nraescolone);
// }
// }
// if (raesdMap.isEmpty()) {
// return;
// }
// System.debug(raesdMap.values().size());
// insert raesdMap.values();
// List raesds = [Select Id, Consum_Apply__c,
// Fixture_Set_Detail__c, IndexFromUniqueKey__c, Consum_Apply_Equipment_Set__c
// FROM Consum_Apply_Equipment_Set_Detail__c
// WHERE Consum_Apply_Equipment_Set__c =: raesdMap.keySet()
// AND Cancel_Select__c = false];
// List raesdList = new List();
// for (Consum_Apply_Equipment_Set_Detail__c raesd : raesds) {
// Consum_Apply_Equipment_Set_Detail__c craesd = new Consum_Apply_Equipment_Set_Detail__c();
// craesd.Consum_Apply_Equipment_Set__c = raesdMap.get(raesd.Consum_Apply_Equipment_Set__c).Id;
// craesd.Consum_Apply__c = raesd.Consum_Apply__c;
// craesd.Fixture_Set_Detail__c = raesd.Fixture_Set_Detail__c;
// craesd.IndexFromUniqueKey__c = raesd.IndexFromUniqueKey__c;
// craesd.Canceled_Id__c = raesd.Id;
// raesdList.add(craesd);
// }
// if (!raesdList.isEmpty()) {
// insert raesdList;
// }
// }
//before 数式の値がnullになる可能性がありますのでここでも一回チェックします
private void formulaToTextCheck() {
List raess = new List();
for (Consum_Apply_Equipment_Set__c nObj : newList) {
if (nObj.Received_Confirm_Status_Text__c != nObj.Received_Confirm_Status_F__c
//|| nObj.Min_Final_reply_day_Text__c != nObj.Min_Final_reply_day_F__c
) {
//Consum_Apply_Equipment_Set__c raes = new Consum_Apply_Equipment_Set__c(Id = nObj.Id);
Consum_Apply_Equipment_Set__c raes = new Consum_Apply_Equipment_Set__c();
raes.Id = nObj.Id;
raes.Received_Confirm_Status_Text__c = nObj.Received_Confirm_Status_F__c;
//raes.Min_Final_reply_day_Text__c = nObj.Min_Final_reply_day_F__c;
raess.add(raes);
}
}
if (!raess.isEmpty()) {
update raess;
}
}
@TestVisible private static void test() {
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++;
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++;
}
}