Java tutorial
/* * Copyright 2012-2013 Danylo Vashchilenko * * 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. */ package org.key2gym.business.services; import java.util.Date; import java.util.LinkedList; import java.util.List; import javax.annotation.security.RolesAllowed; import javax.persistence.NoResultException; import org.joda.time.DateMidnight; import org.joda.time.DateTime; import org.key2gym.business.api.BusinessException; import org.key2gym.business.api.SecurityRoles; import org.key2gym.business.api.SecurityViolationException; import org.key2gym.business.api.ValidationException; import org.key2gym.business.api.dtos.AttendanceDTO; import org.key2gym.business.api.services.AttendancesService; import org.key2gym.business.api.services.OrdersService; import org.key2gym.business.entities.*; import org.key2gym.business.resources.ResourcesManager; import org.key2gym.business.entities.OrderLine; import org.key2gym.business.entities.Property; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * @author Danylo Vashchilenko */ @Service("org.key2gym.business.api.services.AttendancesService") @RolesAllowed({ SecurityRoles.JUNIOR_ADMINISTRATOR, SecurityRoles.SENIOR_ADMINISTRATOR, SecurityRoles.MANAGER }) @Transactional public class AttendancesServiceBean extends BasicBean implements AttendancesService { @Override public Integer checkInRegisteredClient(Integer clientId, Integer keyId) throws BusinessException, ValidationException, SecurityViolationException { if (!callerHasAnyRole(SecurityRoles.JUNIOR_ADMINISTRATOR, SecurityRoles.SENIOR_ADMINISTRATOR, SecurityRoles.MANAGER)) { throw new SecurityViolationException(getString("Security.Operation.Denied")); } Client client; Key key; /* * Arguments validation. */ if (clientId == null) { throw new NullPointerException("The clientId is null."); //NOI18N } if (keyId == null) { throw new NullPointerException("The keyId is null."); //NOI18N } client = getEntityManager().find(Client.class, clientId); if (client == null) { throw new ValidationException(getString("Invalid.Client.ID")); } key = getEntityManager().find(Key.class, keyId); if (key == null) { throw new ValidationException(getString("Invalid.Key.ID")); } if (!getEntityManager().createNamedQuery("Key.findAvailable").getResultList().contains(key)) { //NOI18N throw new BusinessException(getString("BusinessRule.Key.NotAvailable")); } /* * Client should have attendances. */ if (client.getAttendancesBalance() < 1) { throw new BusinessException(getString("BusinessRule.Client.NoAttendancesLeft")); } /* * Client's can't be expired. */ if (client.getExpirationDate().compareTo(new Date()) < 0) { throw new BusinessException(getString("BusinessRule.Client.SubscriptionExpired")); } client.setAttendancesBalance(client.getAttendancesBalance() - 1); /* * Builds an attendance record. */ Attendance attendance = Attendance.apply(key, client); doCalculatePenalties(attendance); getEntityManager().persist(attendance); client.getAttendances().add(attendance); getEntityManager().flush(); return attendance.getId(); } @Override public Integer checkInCasualClient(Integer keyId) throws BusinessException, ValidationException, SecurityViolationException { if (!callerHasAnyRole(SecurityRoles.JUNIOR_ADMINISTRATOR, SecurityRoles.SENIOR_ADMINISTRATOR, SecurityRoles.MANAGER)) { throw new SecurityViolationException(getString("Security.Access.Denied")); } Attendance attendance; Key key; OrderEntity order; /* * Arguments validation. */ if (keyId == null) { throw new NullPointerException("The keyId is null."); //NOI18N } key = getEntityManager().find(Key.class, keyId); if (key == null) { throw new ValidationException(getString("Invalid.Key.ID")); } if (!getEntityManager().createNamedQuery("Key.findAvailable").getResultList().contains(key)) { throw new BusinessException(getString("BusinessRule.Key.NotAvailable")); } attendance = Attendance.apply(key); order = OrderEntity.apply(attendance); ItemSubscription itemSubscription; List<TimeSplit> timeSplits = getEntityManager().createNamedQuery("TimeSplit.findAll") //NOI18N .getResultList(); TimeSplit currentTimeSplit = TimeSplit.selectTimeSplitForTime(timeSplits, timeSource.getLocalTime()); if (currentTimeSplit == null) { throw new BusinessException(getString("BusinessRule.Attendance.Casual.SubscriptionNotAvailable")); } try { itemSubscription = (ItemSubscription) getEntityManager() .createNamedQuery("ItemSubscription.findCasualByTimeSplit") //NOI18N .setParameter("timeSplit", currentTimeSplit) //NOI18N .getSingleResult(); } catch (NoResultException ex) { throw new BusinessException(getString("BusinessRule.Attendance.Casual.SubscriptionNotAvailable")); } OrderLine orderLine = new OrderLine(); orderLine.setItem(itemSubscription.getItem()); orderLine.setOrder(order); orderLine.setQuantity(1); List<OrderLine> orderLines = new LinkedList<>(); orderLines.add(orderLine); order.setOrderLines(orderLines); attendance.setOrder(order); getEntityManager().persist(orderLine); getEntityManager().persist(order); getEntityManager().persist(attendance); getEntityManager().flush(); return attendance.getId(); } @Override public AttendanceDTO getAttendanceById(Integer attendanceId) throws SecurityViolationException { if (!callerHasAnyRole(SecurityRoles.JUNIOR_ADMINISTRATOR, SecurityRoles.SENIOR_ADMINISTRATOR, SecurityRoles.MANAGER)) { throw new SecurityViolationException(getString("Security.Access.Denied")); } if (attendanceId == null) { throw new NullPointerException("The attendanceId is null."); //NOI18N } Attendance attendance = getEntityManager().find(Attendance.class, attendanceId); if (attendance == null) { return null; } AttendanceDTO attendanceDTO = wrapAttendance(attendance); return attendanceDTO; } @Override public List<AttendanceDTO> findAttendancesByDate(DateMidnight date) throws SecurityViolationException { /* * Arguments validation. */ if (date == null) { throw new NullPointerException("The date is null."); //NOI18N } if (!date.equals(DateMidnight.now()) && !callerHasRole(SecurityRoles.MANAGER)) { throw new SecurityException(getString("Security.Access.Denied")); } List<Attendance> attendances = getEntityManager() .createNamedQuery("Attendance.findByDatetimeBeginRangeOrderByDateTimeBeginDesc") //NOI18N .setParameter("low", date.toDate()) //NOI18N .setParameter("high", date.plusDays(1).toDate()) //NOI18N .getResultList(); List<AttendanceDTO> result = new LinkedList<AttendanceDTO>(); for (Attendance attendance : attendances) { result.add(wrapAttendance(attendance)); } return result; } @Override public List<AttendanceDTO> findAttendancesByClient(Integer id) throws ValidationException, SecurityViolationException { if (!callerHasAnyRole(SecurityRoles.JUNIOR_ADMINISTRATOR, SecurityRoles.SENIOR_ADMINISTRATOR, SecurityRoles.MANAGER)) { throw new SecurityViolationException(getString("Security.Access.Denied")); } if (id == null) { throw new NullPointerException("The id is null."); //NOI18N } Client client = getEntityManager().find(Client.class, id); if (client == null) { throw new ValidationException(getString("Invalid.Client.ID")); } List<Attendance> attendances = getEntityManager() .createNamedQuery("Attendance.findByClientOrderByDateTimeBeginDesc").setParameter("client", client) .getResultList(); List<AttendanceDTO> result = new LinkedList<AttendanceDTO>(); for (Attendance attendance : attendances) { result.add(wrapAttendance(attendance)); } return result; } @Override public Boolean isCasual(Integer attendanceId) throws ValidationException, SecurityViolationException { if (!callerHasAnyRole(SecurityRoles.JUNIOR_ADMINISTRATOR, SecurityRoles.SENIOR_ADMINISTRATOR, SecurityRoles.MANAGER)) { throw new SecurityViolationException(getString("Security.Access.Denied")); } if (attendanceId == null) { throw new NullPointerException("The attendanceId is null."); //NOI18N } Attendance attendance = getEntityManager().find(Attendance.class, attendanceId); if (attendance == null) { throw new ValidationException(getString("Invalid.Attendance.ID")); } return attendance.getClient() == null; } @Override public void recalculatePenalties(Integer attendanceId) throws BusinessException, ValidationException, SecurityViolationException { if (attendanceId == null) { throw new NullPointerException("The attendanceId is null."); //NOI18N } Attendance attendance = getEntityManager().find(Attendance.class, attendanceId); if (attendance == null) { throw new ValidationException(ResourcesManager.getString("Invalid.Attendance.ID")); } doCalculatePenalties(attendance); } protected void doCalculatePenalties(Attendance attendance) throws SecurityViolationException, ValidationException, BusinessException { /* * Penalties are only supported with registered clients. */ if (attendance.getClient() != null) { /* * Finds the client's current subscription. */ ItemSubscription itemSubscription; List<ItemSubscription> itemSubscriptions = getEntityManager() .createNamedQuery("ItemSubscription.findByClientOrderByDateRecordedDesc", ItemSubscription.class) //NOI18N .setParameter("client", attendance.getClient()) //NOI18N .getResultList(); if (!itemSubscriptions.isEmpty()) { itemSubscription = itemSubscriptions.get(0); List<TimeSplit> timeSplits = getEntityManager() .createNamedQuery("TimeSplit.findAll", TimeSplit.class) //NOI18N .getResultList(); /* * Calculates the quantity of penalties to apply. */ int penalties = itemSubscription.getTimeSplit().calculatePenalties(timeSplits, timeSource.getLocalTime()); /* * If there are penalties to apply, does it. */ if (penalties > 0) { Integer orderId = ordersService.findByClientIdAndDate(attendance.getClient().getId(), new DateMidnight(), true); Integer itemId = getEntityManager().find(Property.class, "time_range_mismatch_penalty_item_id") .getInteger(); OrderEntity order = getEntityManager().find(OrderEntity.class, orderId); OrderLine targetOrderLine = null; /* * Attempts to find the right order line first. */ for (OrderLine orderLine : order.getOrderLines()) { if (orderLine.getItem().getId() == itemId) { targetOrderLine = orderLine; } } Item penaltyItem = getEntityManager().find(Item.class, itemId); /* * Creates an order line, if it does not exists, and applies * the penalties. */ if (targetOrderLine == null) { targetOrderLine = new OrderLine(); targetOrderLine.setDiscount(null); targetOrderLine.setItem(penaltyItem); targetOrderLine.setOrder(order); targetOrderLine.setQuantity(penalties); getEntityManager().persist(targetOrderLine); order.getOrderLines().add(targetOrderLine); order.getClient().charge(penaltyItem, penalties, null); } else { // We only need to charge penalties that what were not yet charged int newPenalties = penalties - targetOrderLine.getQuantity(); order.getClient().charge(penaltyItem, newPenalties, null); targetOrderLine.setQuantity(penalties); } } } } } @Override public void checkOut(Integer attendanceId) throws BusinessException, ValidationException, SecurityViolationException { if (!callerHasAnyRole(SecurityRoles.JUNIOR_ADMINISTRATOR, SecurityRoles.SENIOR_ADMINISTRATOR, SecurityRoles.MANAGER)) { throw new SecurityViolationException(getString("Security.Operation.Denied")); } if (attendanceId == null) { throw new NullPointerException("The attendanceId is null."); //NOI18N } Attendance attendance = getEntityManager().find(Attendance.class, attendanceId); if (attendance == null) { throw new ValidationException(getString("Invalid.Attendance.ID")); } if (!attendance.isOpen()) { throw new BusinessException(getString("BusinessRule.Attendance.AlreadyClosed")); } OrderEntity order = attendance.getOrder(); /* * If there is an order associated with the attendance, the attendance * is anonymous, and, therefore, the order should have a full payment. */ if (order != null) { if (order.getTotal().compareTo(order.getPayment()) != 0) { throw new BusinessException( getString("BusinessRule.Attendance.Casual.ExactPaymentRequiredToClose")); } } else { doCalculatePenalties(attendance); } attendance.close(); } @Override public Integer findOpenAttendanceByKey(Integer keyId) throws ValidationException, BusinessException, SecurityViolationException { if (!callerHasAnyRole(SecurityRoles.JUNIOR_ADMINISTRATOR, SecurityRoles.SENIOR_ADMINISTRATOR, SecurityRoles.MANAGER)) { throw new SecurityViolationException(getString("Security.Access.Denied")); } /* * Arguments validation. */ if (keyId == null) { throw new NullPointerException("The keyId is null."); // NOI18N } Key key = getEntityManager().find(Key.class, keyId); if (key == null) { throw new ValidationException(getString("Invalid.Key.ID")); } Attendance attendance; try { attendance = (Attendance) getEntityManager().createNamedQuery("Attendance.findOpenByKey") //NOI18N .setParameter("key", key) //NOI18N .getSingleResult(); } catch (NoResultException ex) { throw new BusinessException(getString("Invalid.Key.NoOpenAttendance")); } return attendance.getId(); } /** * Builds an attendance DTO from an attendance entity. * * @param attendance the entity to build DTO from * @return the DTO */ public AttendanceDTO wrapAttendance(Attendance attendance) { AttendanceDTO attendanceDTO = new AttendanceDTO(); attendanceDTO.setId(attendance.getId()); attendanceDTO.setDateTimeBegin(new DateTime(attendance.getDatetimeBegin())); attendanceDTO.setClientId(attendance.getClient() == null ? null : attendance.getClient().getId()); attendanceDTO .setClientFullName(attendance.getClient() == null ? null : attendance.getClient().getFullName()); attendanceDTO.setKeyId(attendance.getKey().getId()); attendanceDTO.setKeyTitle(attendance.getKey().getTitle()); attendanceDTO.setDateTimeEnd(attendance.isOpen() ? null : new DateTime(attendance.getDatetimeEnd())); return attendanceDTO; } @Autowired private OrdersService ordersService; @Autowired private TimeSource timeSource; }