global class InventoryReportDetailArchiveBatch implements Database.Batchable<sObject>, Database.Stateful {
|
private Inventory_Header__c ih_new = new Inventory_Header__c();
|
private String docBodyAsset = ''; // TODO 5M と batch heap size 問題
|
// private String docBodyRaesd = ''; // TODO 5M と batch heap size 問題
|
private String docBodyDiushi = ''; // TODO 5M と batch heap size 問題
|
private String docBodyRepair = ''; // TODO 5M と batch heap size 問題
|
|
private Set<String> defaultAssetField;
|
private Set<String> defaultRaesdField;
|
private Set<String> defaultRepairField;
|
private List<String> cListAssetField = new List<String>();
|
private List<String> cListRaesdField = new List<String>();
|
private List<String> cListRepairField = new List<String>();
|
private Map<String, String> fieldAPIName = new Map<String, String>();
|
private Set<String> defaultTasdField;//20210603 you 1650
|
private List<String> cListTasdField = new List<String>();//20210603 you 1650
|
private String docBodyTasdDiushi = ''; //20210603 you 1650
|
private String docBodyTransfer = ''; //20210604 you 1650
|
|
|
global List<String> emailMessages;
|
global Integer totalCount = 0; // 总件数 (Inventory_Detail__c (Sync_Asset_Record_Flag__c = true))
|
global Integer failedCount = 0;
|
|
@TestVisible
|
private static List<String> messagesForTest;
|
|
/**
|
* 批准后, Trigger 会来调
|
*/
|
global InventoryReportDetailArchiveBatch(Inventory_Header__c ih_new) {
|
this.emailMessages = new List<String>();
|
this.ih_new = ih_new;
|
}
|
|
global Database.QueryLocator start(Database.BatchableContext bc) {
|
bp3_Setting__c conf = bp3_Setting__c.getOrgDefaults();
|
if (String.isBlank(conf.InventoryDetailArchiveFolder__c)) {
|
this.emailMessages.add('未设置CSV保存文件夹,不能开始Batch');
|
failedCount = 0;
|
return Database.getQueryLocator([SELECT Id FROM Inventory_Detail__c LIMIT 0]);
|
}
|
|
Inventory_Batch_Mapping__mdt columns;
|
List<String> keyList;
|
|
defaultAssetField = new Set<String>();
|
defaultRaesdField = new Set<String>();
|
defaultRepairField = new Set<String>();
|
defaultTasdField = new Set<String>();//20210603 you 1650
|
|
|
columns = [select From_Columns__c, Inventory_Columns__c from Inventory_Batch_Mapping__mdt where DeveloperName = 'Asset'];
|
keyList = columns.Inventory_Columns__c.split(',');
|
keyList.addAll(new List<String> {
|
'Inventory_Zaiku_Count_Jia__c',
|
'Inventory_Shipan_Count_Jia__c',
|
'Inventory_Weixiu_Count_Jia__c',
|
'Inventory_Chujie_Count_Jia__c',
|
'Inventory_Daibaofei_Diushi_Count_Jia__c',
|
'Inventory_Quantity_Jia__c',
|
'Inventory_Profit_Quantity__c',
|
'Inventory_Loss_Quantity__c',
|
'Inventory_Deviation_Jia__c',
|
'Inventory_Remarks__c',
|
'Inventory_Diaobo_Count_Jia__c'//20210603 you 1650
|
});
|
for (Integer i = 0; i < keyList.size(); i++) {
|
if (!defaultAssetField.contains(keyList[i])) {
|
cListAssetField.add(keyList[i]);
|
}
|
defaultAssetField.add(keyList[i]);
|
}
|
|
columns = [select From_Columns__c, Inventory_Columns__c from Inventory_Batch_Mapping__mdt where DeveloperName = 'Repair'];
|
keyList = columns.Inventory_Columns__c.split(',');
|
for (Integer i = 0; i < keyList.size(); i++) {
|
if (!defaultRepairField.contains(keyList[i])) {
|
cListRepairField.add(keyList[i]);
|
}
|
defaultRepairField.add(keyList[i]);
|
}
|
|
columns = [select From_Columns__c, Inventory_Columns__c from Inventory_Batch_Mapping__mdt where DeveloperName = 'RAESD'];
|
keyList = columns.Inventory_Columns__c.split(',');
|
for (Integer i = 0; i < keyList.size(); i++) {
|
if (!defaultRaesdField.contains(keyList[i])) {
|
cListRaesdField.add(keyList[i]);
|
}
|
defaultRaesdField.add(keyList[i]);
|
}
|
//20210603 you 1650
|
columns = [select From_Columns__c, Inventory_Columns__c from Inventory_Batch_Mapping__mdt where DeveloperName = 'TASD'];
|
keyList = columns.Inventory_Columns__c.split(',');
|
for (Integer i = 0; i < keyList.size(); i++) {
|
if (!defaultTasdField.contains(keyList[i])) {
|
cListTasdField.add(keyList[i]);
|
}
|
defaultTasdField.add(keyList[i]);
|
}
|
|
//获取label
|
String objectType ='Inventory_Detail__c';
|
Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
|
Schema.SObjectType leadSchema = schemaMap.get(objectType);
|
Map<String, Schema.SObjectField> fieldMap = leadSchema.getDescribe().fields.getMap();
|
|
for(String fieldName : fieldMap.keySet()){
|
fieldAPIName.put(fieldName, fieldMap.get(fieldName).getDescribe().getLabel());
|
}
|
|
Id ih_new_Id = ih_new.Id;
|
String querysql = 'select ' + String.join(new List<String>(defaultAssetField), ', ')
|
+ ' from Inventory_Detail__c '
|
+ 'where Sync_Asset_Record_Flag__c = true'
|
+ ' and Inventory_Header__c = :ih_new_Id';
|
return Database.getQueryLocator(querysql);
|
}
|
|
global void execute(Database.BatchableContext BC, List<Inventory_Detail__c> syncAssetList) {
|
totalCount += syncAssetList.size();
|
System.debug('========='+syncAssetList.size());
|
try {
|
|
String executeBodyAsset = ''; // TODO 5M と batch heap size 問題
|
// String executeBodyRaesd = ''; // TODO 5M と batch heap size 問題
|
String executeBodyDiushi = ''; // TODO 5M と batch heap size 問題
|
String executeBodyRepair = ''; // TODO 5M と batch heap size 問題
|
String executeBodyTasdDiushi = ''; //20210603 you 1650
|
String executeBodyTransfer = ''; //20210604 you 1650
|
String querysql;
|
List<Id> assetIds = new List<Id>();
|
for (Inventory_Detail__c idc : syncAssetList) {
|
assetIds.add(idc.Asset__c);
|
}
|
Id ih_new_Id = ih_new.Id;
|
List<AggregateResult> statusArList = [
|
SELECT Asset_Status__c status, sum(Amount__c) quantity
|
, sum(Inventory_Count__c) invShipanCount, Asset__c assetId
|
, sum(Inventory_Deviation__c) deviaCount
|
, sum(Sync_Asset_Frozen_Quantity__c) lossCount
|
, sum(Sync_Asset_Profit_Quantity__c) profitCount
|
FROM Inventory_Detail__c
|
WHERE Asset__c in :assetIds
|
AND Inventory_Header__c = :ih_new_Id
|
AND Inventory_Time__c <> null
|
GROUP BY Asset_Status__c, Asset__c];
|
//system.debug(statusArList);
|
Map<Id, InventoryReportDetailController.StatusCount> assetCountMap
|
= new Map<Id, InventoryReportDetailController.StatusCount>();
|
for (AggregateResult ar : statusArList) {
|
InventoryReportDetailController.StatusCount statusCount = new InventoryReportDetailController.StatusCount(0);
|
Integer amount = (Integer.valueOf(ar.get('quantity')) == null) ? 0 : Integer.valueOf(ar.get('quantity')); // 应盘数
|
Integer acAmount = (Integer.valueOf(ar.get('invShipanCount')) == null) ? 0 : Integer.valueOf(ar.get('invShipanCount')); // 实盘数
|
Integer wuchaAmount = (Integer.valueOf(ar.get('deviaCount')) == null) ? 0 : Integer.valueOf(ar.get('deviaCount')); // 盘点误差(盘盈/盘亏)
|
Integer lossAmount = (Integer.valueOf(ar.get('lossCount')) == null) ? 0 : Integer.valueOf(ar.get('lossCount')); // 盘点误差(盘盈/盘亏)
|
Integer profitAmount = (Integer.valueOf(ar.get('profitCount')) == null) ? 0 : Integer.valueOf(ar.get('profitCount')); // 盘点误差(盘盈/盘亏)
|
Id assId = String.valueof(ar.get('assetId'));
|
|
if (assetCountMap.containsKey(assId)) {
|
statusCount = assetCountMap.get(assId);
|
}
|
|
if (ar.get('status') == '在库') {
|
statusCount.zaikuNum += amount;
|
} else if (ar.get('status') == '维修中') {
|
statusCount.weixiuNum += amount; // 应盘维修中
|
} else if (ar.get('status') == '出借中') {
|
statusCount.chujieNum += amount; // 应盘出借中
|
} else if (ar.get('status') == '丢失') {
|
statusCount.diushiNum += amount; // 应盘丢失
|
} else if (ar.get('status') == '冻结') {
|
statusCount.zaikuNum += amount; // 盘点在库数='在库'应盘数+'冻结'应盘数
|
}else if (ar.get('status') == '调拨中') {//20210903 you 1650 应盘调拨中
|
statusCount.diaoboNum += amount;
|
}
|
statusCount.quantity += amount; // 应盘数量
|
statusCount.shipanNum += acAmount; // 实盘
|
statusCount.wuchaNum += wuchaAmount; // 盘点误差(盘盈/盘亏)
|
statusCount.panyinNum += profitAmount;
|
statusCount.pankuiNum += lossAmount;
|
assetCountMap.put(assId, statusCount);
|
}
|
system.debug('syncAssetList==='+syncAssetList.size());
|
system.debug('assetCountMap==='+assetCountMap);
|
for (Inventory_Detail__c idc : syncAssetList) {
|
InventoryReportDetailController.StatusCount eachSCount = assetCountMap.get(idc.Asset__c);
|
system.debug(idc.Asset__c+'eachSCount==='+eachSCount);
|
if (eachSCount != null) {
|
idc.Inventory_Zaiku_Count_Jia__c = eachSCount.zaikuNum;
|
idc.Inventory_Shipan_Count_Jia__c = eachSCount.shipanNum;
|
idc.Inventory_Weixiu_Count_Jia__c = eachSCount.weixiuNum;
|
idc.Inventory_Chujie_Count_Jia__c = eachSCount.chujieNum;
|
idc.Inventory_Daibaofei_Diushi_Count_Jia__c = eachSCount.diushiNum;
|
idc.Inventory_Quantity_Jia__c = eachSCount.quantity;
|
idc.Inventory_Deviation_Jia__c = eachSCount.wuchaNum;
|
idc.Inventory_Profit_Quantity__c = eachSCount.panyinNum;
|
idc.Inventory_Loss_Quantity__c = eachSCount.pankuiNum;
|
idc.Inventory_Diaobo_Count_Jia__c = eachSCount.diaoboNum;//20210603 you 1650
|
executeBodyAsset += setDocBodyObject(idc, 'Asset', false);
|
}
|
}
|
|
//借出明细
|
// querysql = 'select ' + String.join(new List<String>(defaultRaesdField), ', ')
|
// + ' from Inventory_Detail__c where Asset__c IN :assetIds and Asset_Status__c = \'出借中\'';
|
// for (Inventory_Detail__c dl : Database.query(querysql)) {
|
// executeBodyRaesd += setDocBodyObject(dl, 'Raesd', false);
|
// }
|
|
//丢失借出明细 备品
|
querysql = 'select ' + String.join(new List<String>(defaultRaesdField), ', ')
|
+ ' from Inventory_Detail__c where Asset__c IN :assetIds and Inventory_Header__c = :ih_new_Id and Asset_Status__c = \'丢失借出明细\'';
|
for (Inventory_Detail__c dl : Database.query(querysql)) {
|
executeBodyDiushi += setDocBodyObject(dl, 'Lost', false);
|
}
|
//丢失调拨明细 调拨 20210603 you 1650
|
querysql = 'select ' + String.join(new List<String>(defaultTasdField), ', ')
|
+ ' from Inventory_Detail__c where Asset__c IN :assetIds and Inventory_Header__c = :ih_new_Id and Asset_Status__c = \'丢失调拨明细\'';
|
for (Inventory_Detail__c tads : Database.query(querysql)) {
|
executeBodyTasdDiushi += setDocBodyObject(tads, 'TransferLost', false);
|
}
|
//调拨中 20210604 you 1650
|
querysql = 'select ' + String.join(new List<String>(defaultTasdField), ', ')
|
+ ' from Inventory_Detail__c where Asset__c IN :assetIds and Inventory_Header__c = :ih_new_Id and Asset_Status__c = \'调拨中\'';
|
for (Inventory_Detail__c tra : Database.query(querysql)) {
|
executeBodyTransfer += setDocBodyObject(tra, 'Transfer', false);
|
}
|
//修理id
|
querysql = 'select ' + String.join(new List<String>(defaultRepairField), ', ')
|
+ ' from Inventory_Detail__c where Asset__c IN :assetIds and Inventory_Header__c = :ih_new_Id and Asset_Status__c = \'维修中\'';
|
for (Inventory_Detail__c rp : Database.query(querysql)) {
|
executeBodyRepair += setDocBodyObject(rp, 'Repair', false);
|
}
|
docBodyAsset += executeBodyAsset;
|
// docBodyRaesd += executeBodyRaesd;
|
docBodyDiushi += executeBodyDiushi;
|
docBodyRepair += executeBodyRepair;
|
docBodyTasdDiushi += executeBodyTasdDiushi;//20210603 you 1650
|
docBodyTransfer += executeBodyTransfer;//20210604 you 1650
|
} catch (Exception e) {
|
failedCount += syncAssetList.size();
|
System.debug(LoggingLevel.ERROR, e.getMessage() + '\n' + e.getStackTraceString());
|
this.emailMessages.add(e.getMessage() + '\n' + e.getStackTraceString());
|
}
|
}
|
|
private String setDocBodyObject(sObject obj, String typeStr, boolean label) {
|
List<String> toCol;
|
if (typeStr == 'Asset') {
|
toCol = cListAssetField;
|
} else if (typeStr == 'Repair') {
|
toCol = cListRepairField;
|
} else if (typeStr == 'Lost') { //20210603 you 1650
|
toCol = cListRaesdField;
|
}else if (typeStr == 'Transfer') { //20210604 you 1650
|
toCol = cListTasdField;
|
} else {
|
toCol = cListTasdField;//20210603 you 1650
|
}
|
Schema.SObjectType targetType = Inventory_Detail__c.sObjectType;
|
Schema.DescribeSObjectResult sobjResult = targetType.getDescribe();
|
Map<string, Schema.SObjectField> m = sobjResult.fields.getMap();
|
String docBody = '';
|
for (Integer i = 0; i < toCol.size(); i++) {
|
List<String> cols = toCol[i].split('\\.');
|
if (obj == null) {
|
if (label) {
|
docBody += fieldAPIName.get(toCol[i].toLowerCase()).escapeCsv();
|
} else {
|
docBody += toCol[i].escapeCsv();
|
}
|
}
|
else {
|
Object val = CreateRelationListPagingCmpCtrl.getObjectValue(obj, cols);
|
if (val != null) {
|
Schema.DescribeFieldResult descField = m.get(toCol[i].toLowerCase().replace('__r.name','__c')).getDescribe();
|
if(descField.getType() == DisplayType.DATETIME && String.isNotBlank('' + val)){
|
docBody += (''+((Datetime) val).addHours(8)).escapeCsv();
|
}
|
else{
|
docBody += ('' + val).escapeCsv();
|
}
|
}
|
}
|
// 加 , 和 行末 的换行
|
if (i < toCol.size() - 1) {
|
docBody += ',';
|
} else {
|
docBody += '\r\n';
|
}
|
}
|
return docBody;
|
}
|
|
public Document getArchiveFilenameForUpsert(String typeStr, Inventory_Header__c ih_new) {
|
bp3_Setting__c conf = bp3_Setting__c.getOrgDefaults();
|
Id folderId = conf.InventoryDetailArchiveFolder__c;
|
String filename = ih_new.Inventory_Start_Date__c.year() + ('' + ih_new.Inventory_Start_Date__c.month()).leftPad(2, '0')
|
+ '_' + ih_new.Internal_asset_location__c + '_' + typeStr + '.csv';
|
|
Document ret = null;
|
List<Document> retList = [SELECT Id
|
, Name
|
, FolderId
|
, Body
|
FROM Document
|
WHERE FolderId = :folderId
|
AND Name =:filename];
|
if (retList.size() > 0) {
|
ret = retList[0];
|
}
|
if (ret == null) {
|
ret = new Document();
|
ret.Name = filename;
|
ret.FolderId = folderId;
|
ret.Type = 'csv';
|
insert ret;
|
}
|
String docBody = setDocBodyObject(null, typeStr, false);
|
docBody += setDocBodyObject(null, typeStr, true);
|
ret.Body = Blob.valueOf(docBody);
|
|
return ret;
|
}
|
|
global void finish(Database.BatchableContext BC) {
|
Integer csvCount = 5; // 总件数 (CSV) 20210726 you 1650
|
|
Integer nullCsvCount = 0;//数据不存在
|
Integer failedCsvCount = 0;//真的失败了
|
|
if (docBodyAsset == '') {
|
nullCsvCount++;
|
this.emailMessages.add('Asset无数据');
|
} else {
|
Document assetDoc = getArchiveFilenameForUpsert('Asset', ih_new);
|
assetDoc.Body = Blob.valueOf(assetDoc.Body.toString() + docBodyAsset);
|
|
Database.SaveResult saveResult = Database.update(assetDoc, false);
|
if (!saveResult.isSuccess()) failedCsvCount++;
|
this.emailMessages = FixtureUtil.setSaveError(new List<Database.SaveResult>{saveResult}, Document.sObjectType, new List<Document>{assetDoc}, this.emailMessages);
|
}
|
|
if (docBodyRepair == '') {
|
nullCsvCount++;
|
this.emailMessages.add('Repair无数据');
|
} else {
|
Document repairDoc = getArchiveFilenameForUpsert('Repair', ih_new);
|
repairDoc.Body = Blob.valueOf(repairDoc.Body.toString() + docBodyRepair);
|
Database.SaveResult saveResult = Database.update(repairDoc, false);
|
if (!saveResult.isSuccess()) failedCsvCount++;
|
this.emailMessages = FixtureUtil.setSaveError(new List<Database.SaveResult>{saveResult}, Document.sObjectType, new List<Document>{repairDoc}, this.emailMessages);
|
}
|
|
// if (docBodyRaesd == '') {
|
// failedCsvCount++;
|
// this.emailMessages.add('Raesd数据不存在');
|
// } else {
|
// Document raesdDoc = getArchiveFilenameForUpsert('Raesd', ih_new);
|
// raesdDoc.Body = Blob.valueOf(raesdDoc.Body.toString() + docBodyRaesd);
|
// Database.SaveResult saveResult = Database.update(raesdDoc, false);
|
// if (!saveResult.isSuccess()) failedCsvCount++;
|
// this.emailMessages = FixtureUtil.setSaveError(new List<Database.SaveResult>{saveResult}, Document.sObjectType, new List<Document>{raesdDoc}, this.emailMessages);
|
// }
|
|
if (docBodyDiushi == '') {
|
nullCsvCount++;
|
this.emailMessages.add('RaesdLost无数据');
|
} else {
|
Document lostDoc = getArchiveFilenameForUpsert('Lost', ih_new);
|
lostDoc.Body = Blob.valueOf(lostDoc.Body.toString() + docBodyDiushi);
|
Database.SaveResult saveResult = Database.update(lostDoc, false);
|
if (!saveResult.isSuccess()) failedCsvCount++;
|
this.emailMessages = FixtureUtil.setSaveError(new List<Database.SaveResult>{saveResult}, Document.sObjectType, new List<Document>{lostDoc}, this.emailMessages);
|
}
|
system.debug('docBodyTasdDiushi=='+docBodyTasdDiushi);
|
//20210603 you 1650 start
|
if (docBodyTasdDiushi == '') {
|
nullCsvCount++;
|
this.emailMessages.add('TransferLost无数据');
|
} else {
|
Document lostDoc = getArchiveFilenameForUpsert('TransferLost', ih_new);
|
lostDoc.Body = Blob.valueOf(lostDoc.Body.toString() + docBodyTasdDiushi);
|
Database.SaveResult saveResult = Database.update(lostDoc, false);
|
if (!saveResult.isSuccess()) failedCsvCount++;
|
this.emailMessages = FixtureUtil.setSaveError(new List<Database.SaveResult>{saveResult}, Document.sObjectType, new List<Document>{lostDoc}, this.emailMessages);
|
}
|
if (docBodyTransfer == '') {
|
nullCsvCount++;
|
this.emailMessages.add('Transfer无数据');
|
} else {
|
Document lostDoc = getArchiveFilenameForUpsert('Transfer', ih_new);
|
lostDoc.Body = Blob.valueOf(lostDoc.Body.toString() + docBodyTransfer);
|
Database.SaveResult saveResult = Database.update(lostDoc, false);
|
if (!saveResult.isSuccess()) failedCsvCount++;
|
this.emailMessages = FixtureUtil.setSaveError(new List<Database.SaveResult>{saveResult}, Document.sObjectType, new List<Document>{lostDoc}, this.emailMessages);
|
}
|
//20210603 you 1650 end
|
|
// TODO wwf email
|
InventoryReportDetailArchiveBatch.messagesForTest = this.emailMessages;
|
// 发 mail
|
BatchEmailUtil be = new BatchEmailUtil();
|
String[] toList = new String[]{};
|
String title = '存档盘点CSV数据';
|
String[] ccList = new String[]{};
|
|
Inventory_Header__c iheader = [select Id, Inventory_Status__c, Name, Internal_asset_location__c, Inventory_Start_Date__c from Inventory_Header__c where Id = :ih_new.Id];
|
String text = '盘点报告书编号:' + iheader.Name + ' 盘点地点:' + iheader.Internal_asset_location__c + ' 盘点开始日:' + iheader.Inventory_Start_Date__c;
|
text += '\n处理对象'+totalCount + '件 保有设备(同期的 盘点明细)';
|
text += '\n处理失败'+failedCount + '件 保有设备(同期的 盘点明细)';
|
|
//if(this.emailMessages.size() == 0){
|
if(failedCsvCount==0){
|
toList.add(UserInfo.getUserEmail());
|
//be.successMail(toList,ccList, title, csvCount, text);
|
be.successMail(toList,ccList, title,
|
String.join(this.emailMessages, '\n'),
|
csvCount,nullCsvCount, text);
|
}else{
|
for(String email : System.Label.Inventory_Result_Email.split(',')){
|
ccList.add(email);
|
}
|
be.failedMail(toList, ccList, title,
|
String.join(this.emailMessages, '\n'),
|
csvCount, csvCount - failedCsvCount-nullCsvCount,nullCsvCount, failedCsvCount,'');
|
}
|
be.send();
|
}
|
}
|