View Javadoc
1   package org.kuali.student.ap.schedulebuilder.support;
2   
3   import org.kuali.student.ap.academicplan.constants.AcademicPlanServiceConstants;
4   import org.kuali.student.ap.academicplan.dto.PlanItemInfo;
5   import org.kuali.student.ap.academicplan.infc.PlanItem;
6   import org.kuali.student.ap.academicplan.service.AcademicPlanService;
7   import org.kuali.student.ap.framework.config.KsapFrameworkServiceLocator;
8   import org.kuali.student.ap.framework.context.CourseHelper;
9   import org.kuali.student.ap.framework.context.PlanConstants;
10  import org.kuali.student.ap.schedulebuilder.ScheduleBuildStrategy;
11  import org.kuali.student.ap.schedulebuilder.ShoppingCartRequest;
12  import org.kuali.student.ap.schedulebuilder.ShoppingCartStrategy;
13  import org.kuali.student.ap.schedulebuilder.dto.ActivityOptionInfo;
14  import org.kuali.student.ap.schedulebuilder.dto.CourseOptionInfo;
15  import org.kuali.student.ap.schedulebuilder.infc.ActivityOption;
16  import org.kuali.student.ap.schedulebuilder.infc.CourseOption;
17  import org.kuali.student.ap.schedulebuilder.infc.PossibleScheduleOption;
18  import org.kuali.student.ap.schedulebuilder.infc.SecondaryActivityOptions;
19  import org.kuali.student.r2.common.dto.ContextInfo;
20  import org.kuali.student.r2.common.exceptions.InvalidParameterException;
21  import org.kuali.student.r2.common.exceptions.MissingParameterException;
22  import org.kuali.student.r2.common.exceptions.OperationFailedException;
23  import org.kuali.student.r2.common.exceptions.PermissionDeniedException;
24  import org.kuali.student.r2.common.infc.Attribute;
25  import org.kuali.student.r2.core.acal.dto.TermInfo;
26  import org.kuali.student.r2.core.acal.infc.Term;
27  import org.kuali.student.r2.lum.course.dto.CourseInfo;
28  
29  import java.io.Serializable;
30  import java.util.ArrayList;
31  import java.util.Arrays;
32  import java.util.Collections;
33  import java.util.HashSet;
34  import java.util.LinkedHashMap;
35  import java.util.List;
36  import java.util.Map;
37  import java.util.Map.Entry;
38  import java.util.Set;
39  
40  public class DefaultShoppingCartStrategy implements ShoppingCartStrategy,
41  		Serializable {
42  
43  	private static final long serialVersionUID = -5919246688332396604L;
44  
45  	@Override
46  	public boolean isCartAvailable(String termId, String campusCode) {
47  		return false;
48  	}
49  
50  	@Override
51  	public List<CourseOption> getCourseOptionsForPlanItem(Term term,
52  			PlanItem planItem) {
53  		ScheduleBuildStrategy scheduleBuildStrategy = KsapFrameworkServiceLocator
54  				.getScheduleBuildStrategy();
55  		assert PlanConstants.COURSE_TYPE.equals(planItem.getRefObjectType());
56  		assert planItem.getPlanTermIds().contains(term.getId());
57  
58  		List<CourseOption> courseOptions = scheduleBuildStrategy
59  				.getCourseOptions(
60  						Collections.singletonList(planItem.getRefObjectId()),
61  						term.getId());
62  
63  		List<String> acodes = Collections.emptyList();
64  		for (Attribute attr : planItem.getAttributes())
65  			if (attr.getKey().equals("activityCode"))
66  				acodes = Arrays.asList(attr.getValue().split(","));
67  
68  		for (CourseOption courseOption : courseOptions) {
69  			for (ActivityOption primaryActivityOption : courseOption
70  					.getActivityOptions()) {
71  				boolean selected = acodes.contains(primaryActivityOption
72  						.getRegistrationCode());
73  				if (selected) {
74  					((ActivityOptionInfo) primaryActivityOption)
75  							.setSelected(true);
76  					for (SecondaryActivityOptions secondaryOptions : primaryActivityOption
77  							.getSecondaryOptions())
78  						for (ActivityOption secondaryActivityOption : secondaryOptions
79  								.getActivityOptions())
80  							if (primaryActivityOption.isEnrollmentGroup())
81  								((ActivityOptionInfo) secondaryActivityOption)
82  										.setLockedIn(primaryActivityOption
83  												.isEnrollmentGroup());
84  							else if (acodes.contains(secondaryActivityOption
85  									.getRegistrationCode()))
86  								((ActivityOptionInfo) secondaryActivityOption)
87  										.setSelected(true);
88  				}
89  			}
90  
91  			// The selected flag on the course option dictates whether we are
92  			// adding or removing from the shopping cart when passed to
93  			// createRequests() --
94  			// When item category is cart, the request will be to remove from the
95  			// cart. For other items types, the request will be to add.
96  			((CourseOptionInfo) courseOption).setSelected(!planItem
97  					.getCategory().equals(
98  							AcademicPlanServiceConstants.ItemCategory.CART));
99  		}
100 		return courseOptions;
101 	}
102 
103 	@Override
104 	public List<ShoppingCartRequest> createRequests(Term term,
105 			List<CourseOption> courseOptions) {
106 		CourseHelper courseHelper = KsapFrameworkServiceLocator
107 				.getCourseHelper();
108 		List<ShoppingCartRequest> requests = new ArrayList<ShoppingCartRequest>(
109 				courseOptions.size());
110 		for (CourseOption courseOption : courseOptions) {
111 			ShoppingCartRequestInfo cartRequest = new ShoppingCartRequestInfo();
112 			cartRequest.setTerm(new TermInfo(term));
113 			cartRequest.setCourse((CourseInfo)courseHelper.getCurrentVersionOfCourse(courseOption
114                     .getCourseId()));
115 			cartRequest.setAddToCart(courseOption.isSelected());
116 
117 			ActivityOption primary = null;
118 			int secondaryLength = 0;
119 			for (ActivityOption primaryActivityOption : courseOption
120 					.getActivityOptions()) {
121 				if (primary == null && primaryActivityOption.isSelected())
122 					primary = primaryActivityOption;
123 				List<SecondaryActivityOptions> secondaryOptions = primaryActivityOption
124 						.getSecondaryOptions();
125 				if (secondaryOptions != null)
126 					secondaryLength = Math.max(secondaryLength,
127 							secondaryOptions.size());
128 			}
129 
130 			List<String> secondaryRegCodes = new ArrayList<String>(
131 					secondaryLength);
132 			if (primary != null) {
133 				cartRequest.setPrimaryRegistrationCode(primary
134 						.getRegistrationCode());
135 
136 				for (SecondaryActivityOptions secondaryOption : primary
137 						.getSecondaryOptions()) {
138 					ActivityOption secondary = null;
139 					for (ActivityOption secondaryActivityOption : secondaryOption
140 							.getActivityOptions())
141 						if (secondary == null
142 								&& secondaryActivityOption.isSelected())
143 							secondary = secondaryActivityOption;
144 					if (secondary != null)
145 						secondaryRegCodes.add(secondary.getRegistrationCode());
146 				}
147 				cartRequest.setSecondaryRegistrationCodes(secondaryRegCodes);
148 			}
149 
150 			requests.add(cartRequest);
151 		}
152 		return requests;
153 	}
154 
155 	private void buildExistingCartOptions(String learningPlanId,
156 			TermInfo termInfo, Map<String, ShoppingCartRequestInfo> rmap) {
157 		AcademicPlanService academicPlanService = KsapFrameworkServiceLocator
158 				.getAcademicPlanService();
159 		ContextInfo context = KsapFrameworkServiceLocator.getContext()
160 				.getContextInfo();
161 		List<PlanItemInfo> planItems;
162 		try {
163 			planItems = academicPlanService.getPlanItemsInPlanByCategory(
164 					learningPlanId, AcademicPlanServiceConstants.ItemCategory.CART,
165 					context);
166 		} catch (InvalidParameterException e) {
167 			throw new IllegalArgumentException("CO lookup failure", e);
168 		} catch (MissingParameterException e) {
169 			throw new IllegalArgumentException("CO lookup failure", e);
170 		} catch (OperationFailedException e) {
171 			throw new IllegalArgumentException("CO lookup failure", e);
172         } catch (PermissionDeniedException e) {
173             throw new IllegalArgumentException("CO lookup permission falure", e);
174         }
175 
176         for (PlanItemInfo planItem : planItems) {
177 			if (!PlanConstants.COURSE_TYPE.equals(planItem.getRefObjectType()))
178 				continue;
179 
180 			List<String> planTermIds = planItem.getPlanTermIds();
181 			if (planTermIds == null || !planTermIds.contains(termInfo.getId()))
182 				continue;
183 
184 			String acodeattr = planItem.getAttributeValue("activityCode");
185 			List<String> acodes;
186 			if (acodeattr == null || acodeattr.isEmpty())
187 				continue;
188 			else
189 				acodes = Arrays.asList(acodeattr.split(","));
190 
191 			String courseId = planItem.getRefObjectId();
192 			ShoppingCartRequestInfo cartRequest = new ShoppingCartRequestInfo();
193 			cartRequest.setAddToCart(false);
194 			cartRequest.setCourse((CourseInfo)KsapFrameworkServiceLocator.getCourseHelper()
195 					.getCurrentVersionOfCourse(courseId));
196 			cartRequest.setPrimaryRegistrationCode(acodes.get(0));
197 			if (acodes.size() > 1)
198 				cartRequest.setSecondaryRegistrationCodes(acodes.subList(1,
199 						acodes.size()));
200 			else
201 				cartRequest.setSecondaryRegistrationCodes(Collections
202 						.<String> emptyList());
203 			cartRequest.setTerm(termInfo);
204 			
205 			rmap.put(courseId, cartRequest);
206 		}
207 
208 	}
209 
210 	@Override
211 	public List<ShoppingCartRequest> createRequests(String learningPlanId,
212 			Term term, PossibleScheduleOption schedule) {
213 		TermInfo termInfo = new TermInfo(term);
214 		Map<String, ShoppingCartRequestInfo> rmap = new LinkedHashMap<String, ShoppingCartRequestInfo>();
215 		buildExistingCartOptions(learningPlanId, termInfo, rmap);
216 
217 		Map<String, List<ActivityOption>> aomap = new LinkedHashMap<String, List<ActivityOption>>();
218 		for (ActivityOption ao : schedule.getActivityOptions()) {
219 			if (ao.isCourseLockedIn())
220 				continue;
221 			List<ActivityOption> aol = aomap.get(ao.getCourseId());
222 			if (aol == null)
223 				aomap.put(ao.getCourseId(),
224 						aol = new ArrayList<ActivityOption>());
225 			aol.add(ao);
226 		}
227 
228 		List<ShoppingCartRequest> rv = new ArrayList<ShoppingCartRequest>(
229 				aomap.size() + rmap.size());
230 		for (Entry<String, List<ActivityOption>> aoe : aomap.entrySet()) {
231 			String courseId = aoe.getKey();
232 
233 			ShoppingCartRequestInfo cartRequest = rmap.remove(courseId);
234 			if (cartRequest != null) {
235 				Set<String> acodes = new HashSet<String>();
236 				acodes.add(cartRequest.getPrimaryRegistrationCode());
237 				for (String regcode : cartRequest
238 						.getSecondaryRegistrationCodes())
239 					acodes.add(regcode);
240 				if (acodes.size() != aoe.getValue().size()) {
241 					rv.add(cartRequest);
242 					cartRequest = null;
243 				} else
244 					aoloop: for (ActivityOption ao : aoe.getValue()) {
245 						if (!acodes.contains(ao.getRegistrationCode())) {
246 							rv.add(cartRequest);
247 							cartRequest = null;
248 							break aoloop;
249 						} else
250 							acodes.remove(ao.getRegistrationCode());
251 					}
252 			}
253 
254 			if (cartRequest == null) {
255 				cartRequest = new ShoppingCartRequestInfo();
256 				cartRequest.setAddToCart(true);
257 				cartRequest.setCourse((CourseInfo)KsapFrameworkServiceLocator
258 						.getCourseHelper().getCurrentVersionOfCourse(courseId));
259 				List<ActivityOption> aol = aoe.getValue();
260                 if(!aol.isEmpty()){
261 				    cartRequest.setPrimaryRegistrationCode(aol.get(0)
262 						.getRegistrationCode());
263                 }
264 				if (aol.size() > 1) {
265 					List<String> scodes = new ArrayList<String>(aol.size() - 1);
266 					for (ActivityOption ao : aol.subList(1, aol.size()))
267 						scodes.add(ao.getRegistrationCode());
268 					cartRequest.setSecondaryRegistrationCodes(scodes);
269 				} else
270 					cartRequest.setSecondaryRegistrationCodes(Collections
271 							.<String> emptyList());
272 				cartRequest.setTerm(termInfo);
273 				rv.add(cartRequest);
274 			}
275 		}
276 		
277 		rv.addAll(rmap.values());
278 
279 		return rv;
280 	}
281 
282 	@Override
283 	public List<ShoppingCartRequest> processRequests(
284 			List<ShoppingCartRequest> requests) {
285 		throw new UnsupportedOperationException(
286 				"Not implemented in KS - override at the institution level");
287 	}
288 
289 }