|
|
@@ -2652,6 +2652,40 @@ func (as *AssetSet) ReconciliationMatch(query Asset) (Asset, bool, error) {
|
|
|
return nil, false, fmt.Errorf("Asset not found to match %s", query)
|
|
|
}
|
|
|
|
|
|
+func (as *AssetSet) ReconciliationMatchMap() map[string]map[string]Asset {
|
|
|
+ matchMap := make(map[string]map[string]Asset)
|
|
|
+
|
|
|
+ for _, asset := range as.assets {
|
|
|
+ props := asset.Properties()
|
|
|
+ // Ignore cloud assets and assets that cannot be matched when looking for reconciliation matches
|
|
|
+ if props == nil || props.ProviderID == "" || asset.Type() == CloudAssetType {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ if _, ok := matchMap[props.ProviderID]; !ok {
|
|
|
+ matchMap[props.ProviderID] = make(map[string]Asset)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check if a match is already in the map
|
|
|
+ if duplicateAsset, ok := matchMap[props.ProviderID][props.Category]; ok {
|
|
|
+ log.DedupedWarningf(5, "duplicate asset found when reconciling for %s", props.ProviderID)
|
|
|
+ // if one asset already has adjustment use that one
|
|
|
+ if duplicateAsset.Adjustment() == 0 && asset.Adjustment() != 0 {
|
|
|
+ matchMap[props.ProviderID][props.Category] = asset
|
|
|
+ } else if duplicateAsset.Adjustment() != 0 && asset.Adjustment() == 0 {
|
|
|
+ matchMap[props.ProviderID][props.Category] = duplicateAsset
|
|
|
+ // otherwise use the one with the higher cost
|
|
|
+ } else if duplicateAsset.TotalCost()-duplicateAsset.Adjustment() < asset.TotalCost()-asset.Adjustment() {
|
|
|
+ matchMap[props.ProviderID][props.Category] = asset
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ matchMap[props.ProviderID][props.Category] = asset
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ return matchMap
|
|
|
+}
|
|
|
+
|
|
|
// Get returns the Asset in the AssetSet at the given key, or nil and false
|
|
|
// if no Asset exists for the given key
|
|
|
func (as *AssetSet) Get(key string) (Asset, bool) {
|