[SDC] Full OnBoard health-check and NFoD support

Change-Id: I606f8a52c7e6d2bd5558f824957d890e552c5423
Signed-off-by: Avi Ziv <avi.ziv@amdocs.com>
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js
index a7c95f6..a371d56 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsActionHelper.js
@@ -17,6 +17,8 @@
 import Configuration from 'sdc-app/config/Configuration.js';
 import {actionTypes as entitlementPoolsActionTypes } from './EntitlementPoolsConstants.js';
 import LicenseModelActionHelper from 'sdc-app/onboarding/licenseModel/LicenseModelActionHelper.js';
+import {actionTypes as limitEditorActions} from 'sdc-app/onboarding/licenseModel/limits/LimitEditorConstants.js';
+import getValue from 'nfvo-utils/getValue.js';
 
 function baseUrl(licenseModelId, version) {
 	const restPrefix = Configuration.get('restPrefix');
@@ -28,18 +30,16 @@
 	return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}`);
 }
 
-function postEntitlementPool(licenseModelId, entitlementPool, version) {
+function postEntitlementPool(licenseModelId, entitlementPool, version) {	
 	return RestAPIUtil.post(baseUrl(licenseModelId, version), {
 		name: entitlementPool.name,
 		description: entitlementPool.description,
 		thresholdValue: entitlementPool.thresholdValue,
-		thresholdUnits: entitlementPool.thresholdUnits,
+		thresholdUnits: getValue(entitlementPool.thresholdUnits),
 		entitlementMetric: entitlementPool.entitlementMetric,
 		increments: entitlementPool.increments,
-		aggregationFunction: entitlementPool.aggregationFunction,
-		operationalScope: entitlementPool.operationalScope,
+		operationalScope: getValue(entitlementPool.operationalScope),
 		time: entitlementPool.time,
-		manufacturerReferenceNumber: entitlementPool.manufacturerReferenceNumber,
 		startDate: entitlementPool.startDate,
 		expiryDate: entitlementPool.expiryDate
 	});
@@ -47,17 +47,16 @@
 
 
 function putEntitlementPool(licenseModelId, previousEntitlementPool, entitlementPool, version) {
+	
 	return RestAPIUtil.put(`${baseUrl(licenseModelId, version)}/${entitlementPool.id}`, {
 		name: entitlementPool.name,
 		description: entitlementPool.description,
 		thresholdValue: entitlementPool.thresholdValue,
-		thresholdUnits: entitlementPool.thresholdUnits,
+		thresholdUnits: getValue(entitlementPool.thresholdUnits),
 		entitlementMetric: entitlementPool.entitlementMetric,
 		increments: entitlementPool.increments,
-		aggregationFunction: entitlementPool.aggregationFunction,
-		operationalScope: entitlementPool.operationalScope,
+		operationalScope: getValue(entitlementPool.operationalScope),
 		time: entitlementPool.time,
-		manufacturerReferenceNumber: entitlementPool.manufacturerReferenceNumber,
 		startDate: entitlementPool.startDate,
 		expiryDate: entitlementPool.expiryDate
 	});
@@ -67,8 +66,43 @@
 	return RestAPIUtil.destroy(`${baseUrl(licenseModelId, version)}/${entitlementPoolId}`);
 }
 
+function fetchLimitsList(licenseModelId, entitlementPoolId, version) {	
+	return RestAPIUtil.fetch(`${baseUrl(licenseModelId, version)}/${entitlementPoolId}/limits`);
+}
+
+function deleteLimit(licenseModelId, entitlementPoolId, version, limitId) {	
+	return RestAPIUtil.destroy(`${baseUrl(licenseModelId, version)}/${entitlementPoolId}/limits/${limitId}`);
+}
+
+function postLimit(licenseModelId, entitlementPoolId, version, limit) {	
+	return RestAPIUtil.post(`${baseUrl(licenseModelId, version)}/${entitlementPoolId}/limits`, {
+		name: limit.name,
+		type: limit.type,
+		description: limit.description,
+		metric: limit.metric,
+		value: limit.value,
+		unit: limit.unit,
+		aggregationFunction: getValue(limit.aggregationFunction),
+		time: getValue(limit.time)
+	});
+}
+
+function putLimit(licenseModelId, entitlementPoolId, version, limit) {
+	
+	return RestAPIUtil.put(`${baseUrl(licenseModelId, version)}/${entitlementPoolId}/limits/${limit.id}`, {
+		name: limit.name,
+		type: limit.type,
+		description: limit.description,
+		metric: limit.metric,
+		value: limit.value,
+		unit: limit.unit,
+		aggregationFunction: getValue(limit.aggregationFunction),
+		time: getValue(limit.time)
+	});	
+}
 
 export default {
+
 	fetchEntitlementPoolsList(dispatch, {licenseModelId, version}) {
 		return fetchEntitlementPoolsList(licenseModelId, version).then(response => dispatch({
 			type: entitlementPoolsActionTypes.ENTITLEMENT_POOLS_LIST_LOADED,
@@ -76,7 +110,10 @@
 		}));
 	},
 
-	openEntitlementPoolsEditor(dispatch, {entitlementPool} = {}) {
+	openEntitlementPoolsEditor(dispatch, {entitlementPool, licenseModelId, version} = {}) {
+		if (licenseModelId && version) {
+			this.fetchLimits(dispatch, {licenseModelId, version, entitlementPool});
+		}
 		dispatch({
 			type: entitlementPoolsActionTypes.entitlementPoolsEditor.OPEN,
 			entitlementPool
@@ -145,5 +182,32 @@
 		LicenseModelActionHelper.fetchLicenseModelById(dispatch, {licenseModelId, version}).then(() => {
 			this.fetchEntitlementPoolsList(dispatch, {licenseModelId, version});
 		});
+	},
+
+
+	fetchLimits(dispatch, {licenseModelId, version, entitlementPool}) {
+		return fetchLimitsList(licenseModelId, entitlementPool.id, version). then (response => {
+			dispatch({
+				type: entitlementPoolsActionTypes.entitlementPoolsEditor.LIMITS_LIST_LOADED,
+				response
+			});
+		});		
+	},
+
+	submitLimit(dispatch, {licenseModelId, version, entitlementPool, limit}) {	
+		const propmise  =  limit.id ? putLimit(licenseModelId,entitlementPool.id, version, limit)
+			: postLimit(licenseModelId,entitlementPool.id, version, limit);
+		return propmise.then(() => {
+			dispatch({
+				type: limitEditorActions.CLOSE
+			});
+			this.fetchLimits(dispatch, {licenseModelId, version, entitlementPool});
+		});		
+	},
+
+	deleteLimit(dispatch, {licenseModelId, version, entitlementPool, limit}) {				
+		return  deleteLimit(licenseModelId,entitlementPool.id, version, limit.id).then(() => {
+			this.fetchLimits(dispatch, {licenseModelId, version, entitlementPool});		
+		});				
 	}
 };
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js
index 761614d..de2a87c 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsConstants.js
@@ -15,7 +15,7 @@
  */
 import keyMirror from 'nfvo-utils/KeyMirror.js';
 import i18n from 'nfvo-utils/i18n/i18n.js';
-import InputOptions, {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
+import InputOptions, {other as optionInputOther} from 'nfvo-components/input/validation/InputOptions.jsx';
 
 export const actionTypes = keyMirror({
 
@@ -28,6 +28,7 @@
 		OPEN: null,
 		CLOSE: null,
 		DATA_CHANGED: null,
+		LIMITS_LIST_LOADED: null
 	}
 
 });
@@ -94,11 +95,6 @@
 		{enum: 'Units_TB', title: 'Units-TB'},
 		{enum: 'Units_GB', title: 'Units-GB'},
 		{enum: 'Units_MB', title: 'Units-MB'}
-	],
-	THRESHOLD_UNITS: [
-		{enum: '', title: i18n('please select…')},
-		{enum: thresholdUnitType.ABSOLUTE, title: 'Absolute'},
-		{enum: thresholdUnitType.PERCENTAGE, title: '%'}
 	]
 };
 
@@ -112,6 +108,11 @@
 	return units === 'Absolute' ? '' : '%';
 };
 
-export const SP_ENTITLEMENT_POOL_FORM = 'SPENTITLEMENTPOOL';
+export const tabIds = {
+	GENERAL: 'GENERAL',
+	SP_LIMITS: 'SP_LIMITS',
+	VENDOR_LIMITS: 'VENDOR_LIMITS',
+	ADD_LIMIT_BUTTON: 'ADD_LIMIT_BUTTON'
+};
 
-export const EP_TIME_FORMAT = 'MM/DD/YYYY';
+export const SP_ENTITLEMENT_POOL_FORM = 'SPENTITLEMENTPOOL';
\ No newline at end of file
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js
index f89cf8f..23c260f 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditor.js
@@ -18,10 +18,12 @@
 import EntitlementPoolsEditorView from './EntitlementPoolsEditorView.jsx';
 import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
 
+import LimitEditorActionHelper from '../limits/LimitEditorActionHelper.js';
+
 const mapStateToProps = ({licenseModel: {entitlementPool}}) => {
 
 
-	let {data, genericFieldInfo, formReady} = entitlementPool.entitlementPoolEditor;
+	let {data, genericFieldInfo, formReady, limitsList} = entitlementPool.entitlementPoolEditor;
 
 	let isFormValid = ValidationHelper.checkFormValid(genericFieldInfo);
 
@@ -33,7 +35,7 @@
 
 	const list = entitlementPool.entitlementPoolsList;
 	for (let i = 0; i < list.length; i++) {
-		EPNames[list[i].name] = list[i].id;
+		EPNames[list[i].name.toLowerCase()] = list[i].id;
 	}
 
 	return {
@@ -42,7 +44,8 @@
 		previousData,
 		isFormValid,
 		formReady,
-		EPNames
+		EPNames,
+		limitsList
 	};
 };
 
@@ -50,11 +53,13 @@
 	return {
 		onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}),
 		onCancel: () => EntitlementPoolsActionHelper.closeEntitlementPoolsEditor(dispatch),
-		onSubmit: ({previousEntitlementPool, entitlementPool}) => {
-			EntitlementPoolsActionHelper.closeEntitlementPoolsEditor(dispatch);
+		onSubmit: ({previousEntitlementPool, entitlementPool, keepOpen}) => {
+			if (!keepOpen) {EntitlementPoolsActionHelper.closeEntitlementPoolsEditor(dispatch);}
 			EntitlementPoolsActionHelper.saveEntitlementPool(dispatch, {licenseModelId, previousEntitlementPool, entitlementPool, version});
 		},
-		onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName)
+		onValidateForm: (formName) => ValidationHelper.validateForm(dispatch, formName),
+		onCloseLimitEditor: () => LimitEditorActionHelper.closeLimitsEditor(dispatch),
+		onOpenLimitEditor: (limit) => LimitEditorActionHelper.openLimitsEditor(dispatch, {limit})
 	};
 };
 
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js
index bc95497..be100f6 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorReducer.js
@@ -41,12 +41,7 @@
 					'description' : {
 						isValid: true,
 						errorText: '',
-						validations: [{type: 'required', data: true}, {type: 'maxLength', data: 1000}]
-					},
-					'manufacturerReferenceNumber' : {
-						isValid: true,
-						errorText: '',
-						validations: [{type: 'required', data: true}, {type: 'maxLength', data: 100}]
+						validations: [{type: 'maxLength', data: 1000}]
 					},
 					'increments' : {
 						isValid: true,
@@ -56,33 +51,18 @@
 					'operationalScope' : {
 						isValid: true,
 						errorText: '',
-						validations: [{type: 'required', data: true}]
+						validations: []
 					},
 					'thresholdUnits' : {
 						isValid: true,
 						errorText: '',
-						validations: [{type: 'required', data: true}]
+						validations: []
 					},
 					'thresholdValue' : {
 						isValid: true,
 						errorText: '',
-						validations: [{type: 'required', data: true}]
-					},
-					'entitlementMetric' : {
-						isValid: true,
-						errorText: '',
-						validations: [{type: 'required', data: true}]
-					},
-					'aggregationFunction' : {
-						isValid: true,
-						errorText: '',
-						validations: [{type: 'required', data: true}]
-					},
-					'time' : {
-						isValid: true,
-						errorText: '',
-						validations: [{type: 'required', data: true}]
-					},
+						validations: []
+					},					
 					'startDate': {
 						isValid: true,
 						errorText: '',
@@ -106,6 +86,12 @@
 			};
 		case actionTypes.entitlementPoolsEditor.CLOSE:
 			return {};
+
+		case actionTypes.entitlementPoolsEditor.LIMITS_LIST_LOADED:
+			return {
+				...state,
+				limitsList: action.response.results
+			};	
 		default:
 			return state;
 	}
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx
index e4b52fc..aa1321c 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsEditorView.jsx
@@ -21,41 +21,39 @@
 import Input from 'nfvo-components/input/validation/Input.jsx';
 import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx';
 import Form from 'nfvo-components/input/validation/Form.jsx';
+import Button from 'sdc-ui/lib/react/Button.js';
 import GridSection from 'nfvo-components/grid/GridSection.jsx';
 import GridItem from 'nfvo-components/grid/GridItem.jsx';
-import {optionsInputValues as  EntitlementPoolsOptionsInputValues, thresholdUnitType, SP_ENTITLEMENT_POOL_FORM, EP_TIME_FORMAT}  from  './EntitlementPoolsConstants.js';
-import {other as optionInputOther} from 'nfvo-components/input/inputOptions/InputOptions.jsx';
+import {optionsInputValues as  EntitlementPoolsOptionsInputValues, SP_ENTITLEMENT_POOL_FORM, tabIds}  from  './EntitlementPoolsConstants.js';
+import {optionsInputValues as LicenseModelOptionsInputValues} from '../LicenseModelConstants.js';
+import {validateStartDate, thresholdValueValidation} from '../LicenseModelValidations.js';
+import {DATE_FORMAT} from 'sdc-app/onboarding/OnboardingConstants.js';
+import {other as optionInputOther} from 'nfvo-components/input/validation/InputOptions.jsx';
+import Tabs from 'sdc-ui/lib/react/Tabs.js';
+import Tab from 'sdc-ui/lib/react/Tab.js';
+import EntitlementPoolsLimits from './EntitlementPoolsLimits.js';
+import {limitType, NEW_LIMIT_TEMP_ID} from '../limits/LimitEditorConstants.js';
 
 const EntitlementPoolPropType = React.PropTypes.shape({
 	id: React.PropTypes.string,
 	name: React.PropTypes.string,
 	description: React.PropTypes.string,
-	manufacturerReferenceNumber: React.PropTypes.string,
 	operationalScope: React.PropTypes.shape({
 		choices: React.PropTypes.array,
 		other: React.PropTypes.string
 	}),
-	aggregationFunction: React.PropTypes.shape({
-		choice: React.PropTypes.string,
-		other: React.PropTypes.string
-	}),
+	thresholdUnits: React.PropTypes.string,
+	thresholdValue: React.PropTypes.number,
 	increments: React.PropTypes.string,
-	time: React.PropTypes.shape({
-		choice: React.PropTypes.string,
-		other: React.PropTypes.string
-	}),
-	entitlementMetric: React.PropTypes.shape({
-		choice: React.PropTypes.string,
-		other: React.PropTypes.string
-	})
+	startDate: React.PropTypes.string,
+	expiryDate: React.PropTypes.string
 });
 
-const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, validateName, validateChoiceWithOther, validateTimeOtherValue,
+const EntitlementPoolsFormContent = ({data, genericFieldInfo, onDataChanged, validateName,
 	 thresholdValueValidation, validateStartDate}) => {
-	let {
-		name, description, manufacturerReferenceNumber, operationalScope , aggregationFunction,  thresholdUnits, thresholdValue,
-		increments, time, entitlementMetric, startDate, expiryDate} = data;
 
+	let {name, description, operationalScope, thresholdUnits, thresholdValue,
+		increments, startDate, expiryDate} = data;
 	return (
 		<GridSection>
 			<GridItem colSpan={2}>
@@ -73,12 +71,10 @@
 				<InputOptions
 					onInputChange={()=>{}}
 					isMultiSelect={true}
-
-					isRequired={true}
 					onEnumChange={operationalScope => onDataChanged({operationalScope:{choices: operationalScope, other: ''}},
-						SP_ENTITLEMENT_POOL_FORM, {operationalScope: validateChoiceWithOther})}
+						SP_ENTITLEMENT_POOL_FORM)}
 					onOtherChange={operationalScope => onDataChanged({operationalScope:{choices: [optionInputOther.OTHER],
-						other: operationalScope}}, SP_ENTITLEMENT_POOL_FORM, {operationalScope: validateChoiceWithOther})}
+						other: operationalScope}}, SP_ENTITLEMENT_POOL_FORM)}
 					label={i18n('Operational Scope')}
 					data-test-id='create-ep-operational-scope'
 					type='select'
@@ -95,21 +91,21 @@
 					errorText={genericFieldInfo.description.errorText}
 					label={i18n('Description')}
 					value={description}
-					isRequired={true}
 					data-test-id='create-ep-description'
 					type='textarea'/>
 			</GridItem>
 			<GridItem colSpan={2}>
 				<div className='threshold-section'>
 					<Input
-						isRequired={true}
 						onChange={e => {
 							// setting the unit to the correct value
 							const selectedIndex = e.target.selectedIndex;
 							const val = e.target.options[selectedIndex].value;
 							onDataChanged({thresholdUnits: val}, SP_ENTITLEMENT_POOL_FORM);
 							// TODO make sure that the value is valid too
-							onDataChanged({thresholdValue: thresholdValue}, SP_ENTITLEMENT_POOL_FORM,{thresholdValue : thresholdValueValidation});}
+							if(thresholdValue && thresholdValue !== '') {
+								onDataChanged({thresholdValue: thresholdValue}, SP_ENTITLEMENT_POOL_FORM,{thresholdValue : thresholdValueValidation});
+							}}
 
 						}
 						value={thresholdUnits}
@@ -120,7 +116,7 @@
 						groupClassName='bootstrap-input-options'
 						className='input-options-select'
 						type='select' >
-						{EntitlementPoolsOptionsInputValues.THRESHOLD_UNITS.map(mtype =>
+						{LicenseModelOptionsInputValues.THRESHOLD_UNITS.map(mtype =>
 							<option key={mtype.enum} value={mtype.enum}>{`${mtype.title}`}</option>)}
 					</Input>
 
@@ -133,116 +129,46 @@
 						errorText={genericFieldInfo.thresholdValue.errorText}
 						data-test-id='create-ep-threshold-value'
 						value={thresholdValue}
-						isRequired={true}
 						type='text'/>
 				</div>
-				<InputOptions
-					onInputChange={()=>{}}
-					isMultiSelect={false}
-					isRequired={true}
-					onEnumChange={entitlementMetric => onDataChanged({entitlementMetric:{choice: entitlementMetric, other: ''}},
-						SP_ENTITLEMENT_POOL_FORM, {entitlementMetric: validateChoiceWithOther})}
-					onOtherChange={entitlementMetric => onDataChanged({entitlementMetric:{choice: optionInputOther.OTHER,
-						other: entitlementMetric}}, SP_ENTITLEMENT_POOL_FORM, {entitlementMetric: validateChoiceWithOther})}
-					label={i18n('Entitlement Metric')}
-					data-test-id='create-ep-entitlement-metric'
-					type='select'
-					required={true}
-					selectedEnum={entitlementMetric && entitlementMetric.choice}
-					otherValue={entitlementMetric && entitlementMetric.other}
-					values={EntitlementPoolsOptionsInputValues.ENTITLEMENT_METRIC}
-					isValid={genericFieldInfo.entitlementMetric.isValid}
-					errorText={genericFieldInfo.entitlementMetric.errorText} />
-				<InputOptions
-					onInputChange={()=>{}}
-					isMultiSelect={false}
-					isRequired={true}
-					onEnumChange={aggregationFunction => onDataChanged({aggregationFunction:{choice: aggregationFunction, other: ''}},
-						SP_ENTITLEMENT_POOL_FORM, {aggregationFunction: validateChoiceWithOther})}
-					onOtherChange={aggregationFunction => onDataChanged({aggregationFunction:{choice: optionInputOther.OTHER,
-						other: aggregationFunction}}, SP_ENTITLEMENT_POOL_FORM, {aggregationFunction: validateChoiceWithOther})}
-					label={i18n('Aggregate Function')}
-					data-test-id='create-ep-aggregate-function'
-					type='select'
-					required={true}
-					selectedEnum={aggregationFunction && aggregationFunction.choice}
-					otherValue={aggregationFunction && aggregationFunction.other}
-					values={EntitlementPoolsOptionsInputValues.AGGREGATE_FUNCTION}
-					isValid={genericFieldInfo.aggregationFunction.isValid}
-					errorText={genericFieldInfo.aggregationFunction.errorText} />
-			</GridItem>
-			<GridItem colSpan={2}>
-				<Input
-					onChange={manufacturerReferenceNumber => onDataChanged({manufacturerReferenceNumber}, SP_ENTITLEMENT_POOL_FORM)}
-					label={i18n('Manufacturer Reference Number')}
-					value={manufacturerReferenceNumber}
-					isValid={genericFieldInfo.manufacturerReferenceNumber.isValid}
-					errorText={genericFieldInfo.manufacturerReferenceNumber.errorText}
-					isRequired={true}
-					data-test-id='create-ep-reference-number'
-					type='text'/>
-			</GridItem>
-			<GridItem colSpan={2}>
-				<InputOptions
-					onInputChange={()=>{}}
-					isMultiSelect={false}
-					isRequired={true}
-					onEnumChange={time => onDataChanged({time:{choice: time, other: ''}},
-						SP_ENTITLEMENT_POOL_FORM, {time: validateChoiceWithOther})}
-					onOtherChange={time => onDataChanged({time:{choice: optionInputOther.OTHER,
-						other: time}}, SP_ENTITLEMENT_POOL_FORM, {time: validateTimeOtherValue})}
-					label={i18n('Time')}
-					data-test-id='create-ep-time'
-					type='select'
-					required={true}
-					selectedEnum={time && time.choice}
-					otherValue={time && time.other}
-					values={EntitlementPoolsOptionsInputValues.TIME}
-					isValid={genericFieldInfo.time.isValid}
-					errorText={genericFieldInfo.time.errorText} />
-			</GridItem>
-			<GridItem colSpan={2}>
 				<Input
 					onChange={increments => onDataChanged({increments}, SP_ENTITLEMENT_POOL_FORM)}
 					label={i18n('Increments')}
 					value={increments}
 					data-test-id='create-ep-increments'
 					type='text'/>
-			</GridItem>
-			<GridItem colSpan={2} />
-			<GridItem colSpan={2}>
-				<Input
-					type='date'
-					label={i18n('Start Date')} 
-					value={startDate}
-					dateFormat={EP_TIME_FORMAT}
-					startDate={startDate}
-					endDate={expiryDate}
-					onChange={startDate => onDataChanged(
-						{startDate: startDate ? startDate.format(EP_TIME_FORMAT) : ''}, 
-						SP_ENTITLEMENT_POOL_FORM,
-						{startDate: validateStartDate}
-					)}
-					isValid={genericFieldInfo.startDate.isValid}
-					errorText={genericFieldInfo.startDate.errorText}
-					selectsStart/>
-			</GridItem>
-			<GridItem colSpan={2}>
-				<Input
-					type='date' 
-					label={i18n('Expiry Date')} 
-					value={expiryDate}
-					dateFormat={EP_TIME_FORMAT}
-					startDate={startDate}
-					endDate={expiryDate}
-					onChange={expiryDate => {
-						onDataChanged({expiryDate: expiryDate ? expiryDate.format(EP_TIME_FORMAT) : ''}, SP_ENTITLEMENT_POOL_FORM);
-						onDataChanged({startDate}, SP_ENTITLEMENT_POOL_FORM, {startDate: validateStartDate});
-					}}
-					isValid={genericFieldInfo.expiryDate.isValid}
-					errorText={genericFieldInfo.expiryDate.errorText}
-					selectsEnd/>
-			</GridItem>
+				<div className='date-section'>
+					<Input
+						type='date'
+						label={i18n('Start Date')}
+						value={startDate}
+						dateFormat={DATE_FORMAT}
+						startDate={startDate}
+						endDate={expiryDate}
+						onChange={startDate => onDataChanged(
+							{startDate: startDate ? startDate.format(DATE_FORMAT) : ''},
+							SP_ENTITLEMENT_POOL_FORM,
+							{startDate: validateStartDate}
+						)}
+						isValid={genericFieldInfo.startDate.isValid}
+						errorText={genericFieldInfo.startDate.errorText}
+						selectsStart/>	
+					<Input
+						type='date'
+						label={i18n('Expiry Date')}
+						value={expiryDate}
+						dateFormat={DATE_FORMAT}
+						startDate={startDate}
+						endDate={expiryDate}
+						onChange={expiryDate => {
+							onDataChanged({expiryDate: expiryDate ? expiryDate.format(DATE_FORMAT) : ''}, SP_ENTITLEMENT_POOL_FORM);
+							onDataChanged({startDate}, SP_ENTITLEMENT_POOL_FORM, {startDate: validateStartDate});
+						}}
+						isValid={genericFieldInfo.expiryDate.isValid}
+						errorText={genericFieldInfo.expiryDate.errorText}
+						selectsEnd/>
+				</div>							
+			</GridItem>									
 		</GridSection>
 	);
 };
@@ -263,42 +189,102 @@
 		data: {}
 	};
 
-	render() {
-		let {data = {}, onDataChanged, isReadOnlyMode, genericFieldInfo} = this.props;
+	componentDidUpdate(prevProps) {				
+		if (this.props.formReady && this.props.formReady !== prevProps.formReady) { // if form validation succeeded -> continue with submit
+			this.submit();
+		}
+	}
+	
+	state = {		
+		selectedTab: tabIds.GENERAL,
+		selectedLimit: ''
+	};
 
+	render() {
+		let {data = {}, onDataChanged, isReadOnlyMode, genericFieldInfo, onCloseLimitEditor, limitsList = []} = this.props;
+		const {selectedTab} = this.state;
+		const isTabsDisabled = !data.id || !this.props.isFormValid;
 
 		return (
 			<div>
-				{
-					genericFieldInfo && <Form
-						ref='validationForm'
-						hasButtons={true}
-						onSubmit={ () => this.submit() }
-						onReset={ () => this.props.onCancel() }
-						labledButtons={true}
-						isReadOnlyMode={isReadOnlyMode}
-						isValid={this.props.isFormValid}
-						formReady={this.props.formReady}
-						onValidateForm={() => this.props.onValidateForm(SP_ENTITLEMENT_POOL_FORM) }
-						className='entitlement-pools-form'>
-						<EntitlementPoolsFormContent
-							data={data}
-							genericFieldInfo={genericFieldInfo}
-							onDataChanged={onDataChanged}
-							validateName={(value)=> this.validateName(value)}
-							validateTimeOtherValue ={(value)=> this.validateTimeOtherValue(value)}
-							validateChoiceWithOther={(value)=> this.validateChoiceWithOther(value)}
-							validateStartDate={(value, state)=> this.validateStartDate(value, state)}
-							thresholdValueValidation={(value, state)=> this.thresholdValueValidation(value, state)}/>
-					</Form>
+			<Tabs 
+				type='menu' 
+				activeTab={selectedTab} 
+				onTabClick={(tabIndex)=>{
+					if (tabIndex === tabIds.ADD_LIMIT_BUTTON)  {
+						this.onAddLimit();
+					} else {
+						this.setState({selectedTab: tabIndex});
+						this.setState({selectedLimit: ''});
+						onCloseLimitEditor();
+					}
+					
+				}} 
+				invalidTabs={[]}>
+				<Tab tabId={tabIds.GENERAL} data-test-id='general-tab' title={i18n('General')}>
+					{
+						genericFieldInfo && <Form
+							ref='validationForm'
+							hasButtons={false}						
+							labledButtons={false}
+							isReadOnlyMode={isReadOnlyMode}
+							isValid={this.props.isFormValid}
+							formReady={this.props.formReady}
+							onValidateForm={() => this.props.onValidateForm(SP_ENTITLEMENT_POOL_FORM) }
+							className='license-model-form entitlement-pools-form'>
+							<EntitlementPoolsFormContent
+								data={data}
+								genericFieldInfo={genericFieldInfo}
+								onDataChanged={onDataChanged}
+								validateName={(value) => this.validateName(value)}
+								validateStartDate={(value, state) => validateStartDate(value, state)}
+								thresholdValueValidation={(value, state) => thresholdValueValidation(value, state)}/>
+						</Form>
+					}
+				</Tab>
+				<Tab disabled={isTabsDisabled} tabId={tabIds.SP_LIMITS} data-test-id='sp-limits-tab' title={i18n('SP Limits')}>
+					{selectedTab === tabIds.SP_LIMITS && 
+						<EntitlementPoolsLimits 
+							limitType={limitType.SERVICE_PROVIDER} 
+							limitsList={limitsList.filter(item => item.type === limitType.SERVICE_PROVIDER)}
+							selectedLimit={this.state.selectedLimit}
+							onCloseLimitEditor={() => this.onCloseLimitEditor()}
+							onSelectLimit={limit => this.onSelectLimit(limit)}/>}
+				</Tab>
+				<Tab disabled={isTabsDisabled} tabId={tabIds.VENDOR_LIMITS} data-test-id='vendor-limits-tab' title={i18n('Vendor Limits')}>
+					{selectedTab === tabIds.VENDOR_LIMITS && 
+						<EntitlementPoolsLimits 
+							limitType={limitType.VENDOR} 
+							limitsList={limitsList.filter(item => item.type === limitType.VENDOR)}
+							selectedLimit={this.state.selectedLimit}
+							onCloseLimitEditor={() => this.onCloseLimitEditor()}
+							onSelectLimit={limit => this.onSelectLimit(limit)}/>}
+				</Tab>
+				{selectedTab !== tabIds.GENERAL ? 
+					<Button disabled={this.state.selectedLimit} className='add-limit-button' tabId={tabIds.ADD_LIMIT_BUTTON} btnType='link' iconName='plus'>{i18n('Add Limit')}</Button> : 
+					<div></div> // Render empty div to not break tabs
 				}
+			</Tabs>
+			<GridSection className='license-model-modal-buttons entitlement-pools-editor-buttons'>
+			{!this.state.selectedLimit && <Button btnType='default' disabled={!this.props.isFormValid} onClick={() => this.submit()} type='reset'>{i18n('Save')}</Button>}
+			<Button btnType={this.state.selectedLimit ? 'default' : 'outline'} onClick={() => this.props.onCancel()} type='reset'>
+				{i18n('Cancel')}
+			</Button>
+			</GridSection>	
 			</div>
 		);
 	}
 
 	submit() {
-		const {data: entitlementPool, previousData: previousEntitlementPool} = this.props;
-		this.props.onSubmit({entitlementPool, previousEntitlementPool});
+		const {data: entitlementPool, previousData: previousEntitlementPool, formReady} = this.props;
+
+		if (!formReady) {
+			this.props.onValidateForm(SP_ENTITLEMENT_POOL_FORM);
+		} else {
+			this.props.onSubmit({entitlementPool, previousEntitlementPool});
+		}
+
+		
 	}
 
 	validateName(value) {
@@ -309,52 +295,26 @@
 		{isValid: false, errorText: i18n('Entitlement pool by the name \'' + value + '\' already exists. Entitlement pool name must be unique')};
 	}
 
-	validateStartDate(value, state) {
-		if (state.data.expiryDate) {
-			if (!value) {
-				return {isValid: false, errorText: i18n('Start date has to be specified if expiry date is specified')};
-			}
+	onSelectLimit(limit) {
+		if (limit.id === this.state.selectedLimit) {
+			this.setState({selectedLimit: ''});
+			return;
 		}
-		return {isValid: true, errorText: ''};
+		this.setState({selectedLimit: limit.id});
+		this.props.onOpenLimitEditor(limit);
 	}
 
-	validateTimeOtherValue(value) {
-		return Validator.validate('time', value.other, [{type: 'required', data: true}, {type: 'numeric', data: true}]);
+	onCloseLimitEditor() {
+		this.setState({selectedLimit: ''});
+		this.props.onCloseLimitEditor();
 	}
 
-	validateChoiceWithOther(value) {
-		let chosen = value.choice;
-		// if we have an empty multiple select we have a problem since it's required
-		if (value.choices) {
-			if (value.choices.length === 0) {
-				return  Validator.validate('field', '', [{type: 'required', data: true}]);
-			} else {
-				// continuing validation with the first chosen value in case we have the 'Other' field
-				chosen = value.choices[0];
-			}
-		}
-		if (chosen !== optionInputOther.OTHER) {
-			return  Validator.validate('field', chosen, [{type: 'required', data: true}]);
-		} else { // when 'Other' was chosen, validate other value
-			return  Validator.validate('field', value.other, [{type: 'required', data: true}]);
-		}
+	onAddLimit() {
+		this.setState({selectedLimit: NEW_LIMIT_TEMP_ID});
+		this.props.onOpenLimitEditor();
 	}
 
-	thresholdValueValidation(value, state) {
 
-		let  unit = state.data.thresholdUnits;
-		if (unit === thresholdUnitType.PERCENTAGE) {
-			return Validator.validate('thresholdValue', value, [
-				{type: 'required', data: true},
-				{type: 'numeric', data: true},
-				{type: 'maximum', data: 100},
-				{type: 'minimum', data: 0}]);
-		} else {
-			return Validator.validate('thresholdValue', value, [
-				{type: 'numeric', data: true},
-				{type: 'required', data: true}]);
-		}
-	}
 
 }
 
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsLimits.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsLimits.js
new file mode 100644
index 0000000..ae53a75
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsLimits.js
@@ -0,0 +1,56 @@
+/*!
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+import {connect} from 'react-redux';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import ValidationHelper from 'sdc-app/common/helpers/ValidationHelper.js';
+import Limits from 'sdc-app/onboarding/licenseModel/limits/Limits.jsx';
+import {actionTypes as globalModalActionTypes} from 'nfvo-components/modal/GlobalModalConstants.js';
+import EntitlementPoolsActionHelper from './EntitlementPoolsActionHelper.js';
+
+const mapStateToProps = ({licenseModel: {entitlementPool: {entitlementPoolEditor: {data}}, limitEditor}, currentScreen}) => {	
+	let  {props: {licenseModelId, version}} = currentScreen;
+	return {
+		parent: data,		
+		limitEditor,
+		licenseModelId,
+		version
+	};
+};
+
+const mapActionsToProps = (dispatch) => {
+	return {
+		onDataChanged: (deltaData, formName, customValidations) => ValidationHelper.dataChanged(dispatch, {deltaData, formName, customValidations}),
+		onSubmit: (limit, entitlementPool, licenseModelId, version) => EntitlementPoolsActionHelper.submitLimit(dispatch,
+			{
+				limit,
+				entitlementPool,
+				licenseModelId,
+				version}),
+		onDelete: ({limit, parent, licenseModelId, version, onCloseLimitEditor, selectedLimit}) => dispatch({
+			type: globalModalActionTypes.GLOBAL_MODAL_WARNING,
+			data:{
+				msg: i18n(`Are you sure you want to delete ${limit.name}?`),
+				confirmationButtonText: i18n('Delete'),
+				title: i18n('Warning'),
+				onConfirmed: ()=> EntitlementPoolsActionHelper.deleteLimit(dispatch, {limit, entitlementPool: parent, licenseModelId, version}).then(() => 
+					selectedLimit === limit.id && onCloseLimitEditor()
+				)
+			}
+		})
+	};
+};
+
+export default connect(mapStateToProps, mapActionsToProps)(Limits);
\ No newline at end of file
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js
index 993ed48..62c6663 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditor.js
@@ -39,7 +39,7 @@
 const mapActionsToProps = (dispatch, {licenseModelId, version}) => {
 	return {
 		onAddEntitlementPoolClick: () => EntitlementPoolsActionHelper.openEntitlementPoolsEditor(dispatch),
-		onEditEntitlementPoolClick: entitlementPool => EntitlementPoolsActionHelper.openEntitlementPoolsEditor(dispatch, {entitlementPool}),
+		onEditEntitlementPoolClick: entitlementPool => EntitlementPoolsActionHelper.openEntitlementPoolsEditor(dispatch, {entitlementPool, licenseModelId, version}),
 		onDeleteEntitlementPool: entitlementPool => dispatch({
 			type: globalMoadlActions.GLOBAL_MODAL_WARNING,
 			data:{
diff --git a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx
index 55fd11b..c730d66 100644
--- a/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/licenseModel/entitlementPools/EntitlementPoolsListEditorView.jsx
@@ -21,7 +21,7 @@
 import ListEditorItemView from 'nfvo-components/listEditor/ListEditorItemView.jsx';
 
 import EntitlementPoolsEditor from './EntitlementPoolsEditor.js';
-import {extractUnits, extractValue} from './EntitlementPoolsConstants';
+import {extractUnits} from './EntitlementPoolsConstants';
 
 class EntitlementPoolsListEditorView extends React.Component {
 	static propTypes = {
@@ -60,7 +60,7 @@
 					isReadOnlyMode={isReadOnlyMode}>
 					{this.filterList().map(entitlementPool => this.renderEntitlementPoolListItem(entitlementPool, isReadOnlyMode))}
 				</ListEditorView>
-				<Modal show={isDisplayModal} bsSize='large' animation={true} className='onborading-modal entitlement-pools-modal'>
+				<Modal show={isDisplayModal} bsSize='large' animation={true} className='onborading-modal license-model-modal entitlement-pools-modal'>
 					<Modal.Header>
 						<Modal.Title>{`${isModalInEditMode ? i18n('Edit Entitlement Pool') : i18n('Create New Entitlement Pool')}`}</Modal.Title>
 					</Modal.Header>
@@ -91,8 +91,7 @@
 	}
 
 	renderEntitlementPoolListItem(entitlementPool, isReadOnlyMode) {
-		let {id, name, description, thresholdValue, thresholdUnits, entitlementMetric, aggregationFunction,
-			manufacturerReferenceNumber, time} = entitlementPool;
+		let {id, name, description, thresholdValue, thresholdUnits} = entitlementPool;
 		let {onEditEntitlementPoolClick, onDeleteEntitlementPool} = this.props;
 		return (
 			<ListEditorItemView
@@ -109,13 +108,7 @@
 
 				<div className='list-editor-item-view-field'>
 					<div className='title'>{i18n('Entitlement')}</div>
-					<div className='entitlement-parameters'>{`${extractValue(aggregationFunction)} ${extractValue(entitlementMetric)} per  ${extractValue(time)}`}</div>
-					<div className='entitlement-pools-count'>{`${thresholdValue ? thresholdValue : ''} ${extractUnits(thresholdUnits)}`}</div>
-				</div>
-
-				<div className='list-editor-item-view-field'>
-					<div className='title'>{i18n('Manufacturer Reference Number')}</div>
-					<div className='text contract-number'>{manufacturerReferenceNumber}</div>
+					<div className='entitlement-pools-count'>{thresholdValue && `${thresholdValue} ${extractUnits(thresholdUnits)}`}</div>
 				</div>
 
 				<div className='list-editor-item-view-field'>