Index: D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/src/org/mifos/application/productdefinition/business/PrdOfferingBO.hbm.xml
===================================================================
--- D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/src/org/mifos/application/productdefinition/business/PrdOfferingBO.hbm.xml	(revision 12273)
+++ D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/src/org/mifos/application/productdefinition/business/PrdOfferingBO.hbm.xml	(working copy)
@@ -345,7 +347,7 @@
 	</query>
 	<query name="product.retrieveProductOfferingMix">
 		<![CDATA[from org.mifos.application.productdefinition.business.PrdOfferingBO prdOffering
-        where prdOffering.prdMixFlag =1
+        where prdOffering.prdMixFlag =1 order by prdOffering.prdOfferingName
 		]]>
 	</query>
 </hibernate-mapping>
Index: D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/src/org/mifos/application/productsmix/struts/action/ProductMixAction.java
===================================================================
--- D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/src/org/mifos/application/productsmix/struts/action/ProductMixAction.java	(revision 12273)
+++ D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/src/org/mifos/application/productsmix/struts/action/ProductMixAction.java	(working copy)
@@ -52,6 +52,7 @@
 import org.mifos.application.productdefinition.business.ProductCategoryBO;
 import org.mifos.application.productdefinition.business.ProductTypeEntity;
 import org.mifos.application.productdefinition.business.SavingsOfferingBO;
+import org.mifos.application.productdefinition.business.service.ProductCategoryBusinessService;
 import org.mifos.application.productdefinition.util.helpers.ProductDefinitionConstants;
 import org.mifos.application.productdefinition.util.helpers.ProductType;
 import org.mifos.application.productsmix.business.ProductMixBO;
@@ -576,6 +577,9 @@
 			}
 		}
 		SessionUtils.setCollectionAttribute(
+				ProductDefinitionConstants.PRODUCTCATEGORYLIST,
+				getAllCategories(userContext), request);
+		SessionUtils.setCollectionAttribute(
 				ProductDefinitionConstants.PRODUCTMIXLIST,
 				getPrdMixBusinessService().getPrdOfferingMix(), request);
 
@@ -697,6 +701,20 @@
 		prdOfferingBO = null;
 		return mapping.findForward(ActionForwards.update_success.toString());
 	}
-
-
+	private List<ProductCategoryBO> getAllCategories(UserContext userContext)
+			throws Exception {
+		List<ProductCategoryBO> productCategoryList = getCategoryBusinessService()
+				.getAllCategories();
+		if (productCategoryList != null) {
+			for (ProductCategoryBO productCategoryBO : productCategoryList) {
+				productCategoryBO.getPrdCategoryStatus().setLocaleId(
+						userContext.getLocaleId());
+				productCategoryBO.getProductType().setUserContext(userContext);
+			}
+		}
+		return productCategoryList;
+	}
+	private ProductCategoryBusinessService getCategoryBusinessService() {
+		return new ProductCategoryBusinessService();
+	}
 }
Index: D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/src/org/mifos/doc-root/application/productsmix/jsp/viewProductsMix.jsp
===================================================================
--- D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/src/org/mifos/doc-root/application/productsmix/jsp/viewProductsMix.jsp	(revision 12273)
+++ D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/src/org/mifos/doc-root/application/productsmix/jsp/viewProductsMix.jsp	(working copy)
@@ -82,37 +82,58 @@
 							<font class="fontnormalRedBold"><html-el:errors
 								bundle="ProductDefUIResources" /> </font>
 							</span>
-							<c:forEach var="productMix"
-								items="${session:getFromSession(sessionScope.flowManager,requestScope.currentFlowKey,'ProductMixList')}">
+							<c:forEach var="productCategory"
+								items="${session:getFromSession(sessionScope.flowManager,requestScope.currentFlowKey,'ProductCategoryList')}">
+							
 								<c:if	test="${empty id}">
 									<c:set var="id"
-										value="${productMix.prdCategory.productType.productTypeID}" />
+										value="${productCategory.productType.productTypeID}" />
 									<table width="95%" border="0" cellspacing="0" cellpadding="0">
 										<tr>
 											<td width="61%">
 											   <span class="fontnormalbold">
-												 <c:out value="${productMix.prdCategory.productType.name}" />
+												 <c:out value="${productCategory.productType.name}" />
 											   </span>
 											 </td>
 										</tr>
 									</table>
+								<c:forEach var="productMix"
+								items="${session:getFromSession(sessionScope.flowManager,requestScope.currentFlowKey,'ProductMixList')}">	
+								<c:if	test="${!empty id && id == productMix.prdCategory.productType.productTypeID}">	
+									<span class="fontnormalbold"> </span>								
+								<table width="90%" border="0" cellspacing="0" cellpadding="0">
+									<tr class="fontnormal">
+										<td width="1%"><img
+											src="pages/framework/images/bullet_circle.gif" width="9"
+											height="11"></td>
+										<td width="99%"><html-el:link
+											href="productMixAction.do?method=get&prdOfferingId=${productMix.prdOfferingId}&productType=${productMix.prdType.productTypeID}&randomNUm=${sessionScope.randomNUm}">
+											<c:out value="${productMix.prdOfferingName}" />
+										</html-el:link>
+										</td>
+									</tr>
+								</table>
 								</c:if>
+								</c:forEach>
+								<br>
+								</c:if>
 								<c:if
-									test="${!empty id && id != productMix.prdCategory.productType.productTypeID}">
+									test="${!empty id && id != productCategory.productType.productTypeID}">
 									<c:set var="id"
-										value="${productMix.prdCategory.productType.productTypeID}" />
-									<br>
+										value="${productCategory.productType.productTypeID}" />
 									<table width="95%" border="0" cellspacing="0" cellpadding="0">
 										<tr>
 											<td width="61%">
 											   <span class="fontnormalbold">
-												 <c:out value="${productMix.prdCategory.productType.name}" />
+												 <c:out value="${productCategory.productType.name}" />
 											   </span>
 											 </td>
 										</tr>
 									</table>
-								</c:if>
-								<span class="fontnormalbold"> </span>								
+								<c:forEach var="productMix"
+								items="${session:getFromSession(sessionScope.flowManager,requestScope.currentFlowKey,'ProductMixList')}">	
+								<c:if	test="${!empty id && id == productMix.prdCategory.productType.productTypeID}">	
+									<span class="fontnormalbold"> </span>								
 								<table width="90%" border="0" cellspacing="0" cellpadding="0">
 									<tr class="fontnormal">
 										<td width="1%"><img
@@ -125,6 +146,9 @@
 										</td>
 									</tr>
 								</table>
+								</c:if>
+								</c:forEach>	
+								</c:if>							
 							</c:forEach>
 							<html-el:hidden property="currentFlowKey" value="${requestScope.currentFlowKey}" />
 						</html-el:form>
Index: D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/test/org/mifos/application/productdefinition/persistence/PrdOfferingPersistenceTest.java
===================================================================
--- D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/test/org/mifos/application/productdefinition/persistence/PrdOfferingPersistenceTest.java	(revision 12273)
+++ D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/test/org/mifos/application/productdefinition/persistence/PrdOfferingPersistenceTest.java	(working copy)
@@ -1,27 +1,57 @@
 package org.mifos.application.productdefinition.persistence;
 
+import static org.mifos.application.meeting.util.helpers.MeetingType.CUSTOMER_MEETING;
+import static org.mifos.application.meeting.util.helpers.RecurrenceType.WEEKLY;
+import static org.mifos.framework.util.helpers.TestObjectFactory.EVERY_WEEK;
+
+import java.sql.Date;
 import java.util.List;
 
 import org.mifos.application.accounts.savings.util.helpers.SavingsTestHelper;
+import org.mifos.application.customer.business.CustomerBO;
+import org.mifos.application.meeting.business.MeetingBO;
+import org.mifos.application.productdefinition.business.LoanOfferingBO;
+import org.mifos.application.productdefinition.business.PrdOfferingBO;
 import org.mifos.application.productdefinition.business.PrdStatusEntity;
 import org.mifos.application.productdefinition.business.SavingsOfferingBO;
 import org.mifos.application.productdefinition.util.helpers.PrdCategoryStatus;
 import org.mifos.application.productdefinition.util.helpers.PrdStatus;
 import org.mifos.application.productdefinition.util.helpers.ProductType;
+import org.mifos.application.productsmix.business.ProductMixBO;
+import org.mifos.application.productsmix.business.service.ProductMixBusinessService;
 import org.mifos.framework.MifosTestCase;
+import org.mifos.framework.business.service.ServiceFactory;
 import org.mifos.framework.exceptions.PersistenceException;
+import org.mifos.framework.exceptions.ServiceException;
 import org.mifos.framework.hibernate.helper.HibernateUtil;
+import org.mifos.framework.util.helpers.BusinessServiceName;
 import org.mifos.framework.util.helpers.TestObjectFactory;
 
 public class PrdOfferingPersistenceTest extends MifosTestCase {
 
+	private LoanOfferingBO loanOffering;
+	private LoanOfferingBO loanOffering2;
+
+	private PrdOfferingPersistence persistence;
+	
+	MeetingBO meetingIntCalc;
+	MeetingBO meetingIntCalc2;
+	ProductMixBO prdmix;
+	ProductMixBO prdmix2;
 	@Override
 	protected void setUp() throws Exception {
 		super.setUp();
+		persistence = new PrdOfferingPersistence();
 	}
 
 	@Override
 	protected void tearDown() throws Exception {
+		TestObjectFactory.removeObject(prdmix);	
+		TestObjectFactory.removeObject(prdmix2);	
+		TestObjectFactory.removeObject(loanOffering);
+		TestObjectFactory.removeObject(loanOffering2);
+		
+		HibernateUtil.closeSession();
 		super.tearDown();
 	}
 
@@ -148,4 +178,46 @@
 				assertEquals("InActive", prdStatus.getPrdState().getName());
 		}
 	}
+	public void testGetPrdOfferingMix() throws ServiceException, PersistenceException {
+		createLoanProductMixed();
+		createsecondLoanProductMixed();
+		prdmix=createNotAllowedProductForAProductOffering(loanOffering,loanOffering);
+		assertEquals(2, persistence.getPrdOfferingMix().size());
+		assertTrue("Products Mix should be in alphabitical order:",
+				(persistence.getPrdOfferingMix().get(0).getPrdOfferingName().compareToIgnoreCase(persistence
+						.getPrdOfferingMix().get(1).getPrdOfferingName())) < 0);
+		HibernateUtil.closeSession();
+
+	}
+	private void createLoanProductMixed() throws PersistenceException {
+
+		Date startDate = new Date(System.currentTimeMillis());
+
+		meetingIntCalc = TestObjectFactory.createMeeting(TestObjectFactory
+				.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING));
+
+		loanOffering = TestObjectFactory.createLoanOffering("BLoan", "L",
+				startDate, meetingIntCalc);
+		loanOffering.updatePrdOfferingFlag();
+
+	}
+	private void createsecondLoanProductMixed() throws PersistenceException {
+
+		Date startDate = new Date(System.currentTimeMillis());
+
+		meetingIntCalc = TestObjectFactory.createMeeting(TestObjectFactory
+				.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING));
+
+		loanOffering2 = TestObjectFactory.createLoanOffering("ALoan", "aL",
+				startDate, meetingIntCalc);
+		loanOffering2.updatePrdOfferingFlag();
+
+	}
+	private  ProductMixBO createNotAllowedProductForAProductOffering(PrdOfferingBO prdOffering,PrdOfferingBO prdOfferingNotAllowedId)
+	{
+		return TestObjectFactory.createNotAllowedProductForAProductOffering(prdOffering,prdOfferingNotAllowedId);
+		
+	}
 }
Index: D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/test/org/mifos/application/productsmix/business/service/ProductMixBusinessServiceTest.java
===================================================================
--- D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/test/org/mifos/application/productsmix/business/service/ProductMixBusinessServiceTest.java	(revision 12273)
+++ D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/test/org/mifos/application/productsmix/business/service/ProductMixBusinessServiceTest.java	(working copy)
@@ -10,10 +10,13 @@
 import org.mifos.application.customer.center.business.CenterBO;
 import org.mifos.application.meeting.business.MeetingBO;
 import org.mifos.application.productdefinition.business.LoanOfferingBO;
+import org.mifos.application.productdefinition.business.PrdOfferingBO;
 import org.mifos.application.productdefinition.business.SavingsOfferingBO;
 import org.mifos.application.productdefinition.util.helpers.ProductType;
+import org.mifos.application.productsmix.business.ProductMixBO;
 import org.mifos.framework.MifosTestCase;
 import org.mifos.framework.business.service.ServiceFactory;
+import org.mifos.framework.exceptions.PersistenceException;
 import org.mifos.framework.exceptions.ServiceException;
 import org.mifos.framework.hibernate.helper.HibernateUtil;
 import org.mifos.framework.util.helpers.BusinessServiceName;
@@ -23,12 +26,18 @@
 public class ProductMixBusinessServiceTest  extends MifosTestCase {
 	
 	private SavingsOfferingBO savingsOffering;
+	private SavingsOfferingBO secondSavingsOffering;
 	private LoanOfferingBO loanOffering;
+	private LoanOfferingBO loanOffering2;
 	private CustomerBO center;	
+	private CustomerBO center2;	
 	private ProductMixBusinessService service;
 	MeetingBO meetingIntPost;
 	MeetingBO meetingIntCalc;
-	
+	MeetingBO meetingIntPost2;
+	MeetingBO meetingIntCalc2;
+	ProductMixBO prdmix;
+	ProductMixBO prdmix2;
 	@Override
 	protected void setUp() throws Exception {
 		super.setUp();
@@ -39,9 +48,15 @@
 
 	@Override
 	protected void tearDown() throws Exception {
+		TestObjectFactory.removeObject(prdmix);	
+		TestObjectFactory.removeObject(prdmix2);	
 		TestObjectFactory.removeObject(loanOffering);
+		TestObjectFactory.removeObject(loanOffering2);
 		TestObjectFactory.removeObject(savingsOffering);
+		TestObjectFactory.removeObject(secondSavingsOffering);
 		TestObjectFactory.cleanUp(center);
+		TestObjectFactory.cleanUp(center2);
+		
 		HibernateUtil.closeSession();
 		super.tearDown();
 	}
@@ -72,9 +87,25 @@
 	
 	
 	public void testGetAllowedPrdOfferingsByType() throws ServiceException {
-		assertEquals(1, service.getAllowedPrdOfferingsByType(
+		createSecondSavingProduct();
+		assertEquals(2, service.getAllowedPrdOfferingsByType(
 				savingsOffering.getPrdOfferingId().toString(),
 				ProductType.SAVINGS.getValue().toString()).size());
+
+		assertEquals("A_SavingPrd", service.getAllowedPrdOfferingsByType(
+				savingsOffering.getPrdOfferingId().toString(),
+				ProductType.SAVINGS.getValue().toString()).get(0)
+				.getPrdOfferingName());
+
+		assertTrue("Savings products should be in alphabitical order:",
+				(service.getAllowedPrdOfferingsByType(
+						savingsOffering.getPrdOfferingId().toString(),
+						ProductType.SAVINGS.getValue().toString()).get(0)
+						.getPrdOfferingName().compareToIgnoreCase(service
+						.getAllowedPrdOfferingsByType(
+								savingsOffering.getPrdOfferingId().toString(),
+								ProductType.SAVINGS.getValue().toString()).get(
+								1).getPrdOfferingName())) < 0);
 		HibernateUtil.closeSession();
 
 	}
@@ -90,10 +121,27 @@
 	
 	
 	public void testGetNotAllowedPrdOfferingsByType_success() throws ServiceException {
-		assertEquals(0, service.getNotAllowedPrdOfferingsByType(savingsOffering.getPrdOfferingId().toString()).size());
+		createSecondSavingProduct();
+		prdmix2=createNotAllowedProductForAProductOffering(savingsOffering,savingsOffering);
+		prdmix=createNotAllowedProductForAProductOffering(savingsOffering,secondSavingsOffering);
+		
+		assertEquals(2, service.getNotAllowedPrdOfferingsByType(savingsOffering.getPrdOfferingId().toString()).size());
+		
+		assertTrue("Savings products should be in alphabitical order:",
+				(service.getNotAllowedPrdOfferingsByType(savingsOffering.getPrdOfferingId().toString()).get(0)
+						.getPrdOfferingName().compareToIgnoreCase(service
+						.getNotAllowedPrdOfferingsByType(savingsOffering.getPrdOfferingId().toString()).get(
+								1).getPrdOfferingName())) < 0);
+
 		HibernateUtil.closeSession();
 	}
 
+	private  ProductMixBO createNotAllowedProductForAProductOffering(PrdOfferingBO prdOffering,PrdOfferingBO prdOfferingNotAllowedId)
+	{
+		return TestObjectFactory.createNotAllowedProductForAProductOffering(prdOffering,prdOfferingNotAllowedId);
+		
+	}
+	
 	private CenterBO createCenter() {
 		return createCenter("Center_Active_test");
 	}
@@ -119,5 +167,55 @@
 			meetingIntCalc, meetingIntPost);
 
 	}
+	private void createSecondSavingProduct() {
+		Date startDate = new Date(System.currentTimeMillis());
+		meetingIntCalc2 = TestObjectFactory.createMeeting(TestObjectFactory
+				.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING));
+		meetingIntPost2 = TestObjectFactory.createMeeting(TestObjectFactory
+				.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING));
 
+		center2 = createCenter("Center_Active_test2");
+
+		secondSavingsOffering =
+			TestObjectFactory.createSavingsProduct("A_SavingPrd", "AS",
+				startDate,
+				meetingIntCalc2, meetingIntPost2);
+
+		}
+	public void testGetPrdOfferingMix() throws ServiceException, PersistenceException {
+		createLoanProductMixed();
+		createsecondLoanProductMixed();
+		prdmix=createNotAllowedProductForAProductOffering(loanOffering,loanOffering);
+		assertEquals(2, service.getPrdOfferingMix().size());
+		assertTrue("Products Mix should be in alphabitical order:",
+				(service.getPrdOfferingMix().get(0).getPrdOfferingName().compareToIgnoreCase(service
+						.getPrdOfferingMix().get(1).getPrdOfferingName())) < 0);
+		HibernateUtil.closeSession();
+
+	}
+	
+	private void createLoanProductMixed() throws PersistenceException {
+
+		Date startDate = new Date(System.currentTimeMillis());
+
+		meetingIntCalc = TestObjectFactory.createMeeting(TestObjectFactory
+				.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING));
+
+		loanOffering = TestObjectFactory.createLoanOffering("Loan", "L",
+				startDate, meetingIntCalc);
+		loanOffering.updatePrdOfferingFlag();
+
+	}
+	private void createsecondLoanProductMixed() throws PersistenceException {
+
+		Date startDate = new Date(System.currentTimeMillis());
+
+		meetingIntCalc = TestObjectFactory.createMeeting(TestObjectFactory
+				.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING));
+
+		loanOffering2 = TestObjectFactory.createLoanOffering("aLoan", "aL",
+				startDate, meetingIntCalc);
+		loanOffering2.updatePrdOfferingFlag();
+
+	}
 }
Index: D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/test/org/mifos/framework/util/helpers/TestObjectFactory.java
===================================================================
--- D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/test/org/mifos/framework/util/helpers/TestObjectFactory.java	(revision 12273)
+++ D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/test/org/mifos/framework/util/helpers/TestObjectFactory.java	(working copy)
@@ -150,6 +150,7 @@
 import org.mifos.application.productdefinition.business.LoanOfferingBO;
 import org.mifos.application.productdefinition.business.LoanOfferingBOTest;
 import org.mifos.application.productdefinition.business.PrdApplicableMasterEntity;
+import org.mifos.application.productdefinition.business.PrdOfferingBO;
 import org.mifos.application.productdefinition.business.PrdOfferingMeetingEntity;
 import org.mifos.application.productdefinition.business.PrdStatusEntity;
 import org.mifos.application.productdefinition.business.ProductCategoryBO;
@@ -320,6 +321,21 @@
 		return center;
 	}
 
+
+	public static ProductMixBO createNotAllowedProductForAProductOffering(PrdOfferingBO prdOffering,PrdOfferingBO prdOfferingNotAllowedId) {
+		ProductMixBO prdmix;
+		try {
+			prdmix = new ProductMixBO(prdOffering,prdOfferingNotAllowedId);
+			prdmix.save();
+			HibernateUtil.commitTransaction();
+		}
+		catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		addObject(prdmix);
+		return prdmix;
+	}
+	
 	public static List<FeeView> getFees() {
 		List<FeeView> fees = new ArrayList<FeeView>();
 		AmountFeeBO maintenanceFee = (AmountFeeBO) createPeriodicAmountFee(
Index: D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/src/org/mifos/application/productsmix/business/ProductMixBO.java
===================================================================
--- D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/src/org/mifos/application/productsmix/business/ProductMixBO.java	(revision 12273)
+++ D:/MyWorkSpace/Job/Enda/Mifos2009/mifos/src/org/mifos/application/productsmix/business/ProductMixBO.java	(working copy)
@@ -115,8 +115,16 @@
 			throw new ProductDefinitionException(e);
 		}
 	}
-
 	
+	public void save() throws ProductDefinitionException {
+		try {
+			new ProductMixPersistence().createOrUpdate(this);
+		}
+		catch (PersistenceException e) {
+			throw new ProductDefinitionException(e);
+		}
+	}
+	
 	public boolean doesPrdOfferingsCanCoexist(Short idPrdOff_A, Short idPrdOff_B)
 			throws PersistenceException {
 		try {
