/* * Copyright (c) 2016 Haulmont * * 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 com.haulmont.timesheets.gui.approve; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import com.haulmont.cuba.core.global.TimeSource; import com.haulmont.cuba.core.global.View; import com.haulmont.cuba.gui.components.*; import com.haulmont.cuba.security.global.UserSession; import com.haulmont.timesheets.entity.TimeEntry; import com.haulmont.timesheets.entity.TimeEntryStatus; import com.haulmont.timesheets.global.WorkTimeConfigBean; import com.haulmont.timesheets.global.WorkdaysTools; import com.haulmont.timesheets.gui.timeentry.AllTimeEntries; import com.haulmont.timesheets.gui.util.ComponentsHelper; import com.haulmont.timesheets.gui.util.TimeEntryOvertimeAggregation; import org.apache.commons.lang.time.DateUtils; import javax.inject.Inject; import java.math.BigDecimal; import java.util.*; import java.util.Calendar; /** * @author gorelov */ public class BulkTimeEntriesApprove extends AllTimeEntries { @Inject protected DateField dateFrom; @Inject protected DateField dateTo; @Inject protected TimeSource timeSource; @Inject protected PopupButton approve; @Inject protected PopupButton reject; @Inject protected LookupField status; @Inject protected LookupField user; @Inject protected UserSession userSession; @Inject protected WorkdaysTools workdaysTools; @Inject protected WorkTimeConfigBean workTimeConfigBean; @Override public void init(Map<String, Object> params) { super.init(params); if (securityAssistant.isSuperUser()) { timeEntriesDs.setQuery("select e from ts$TimeEntry e " + "where e.date >= :component$dateFrom and e.date <= :component$dateTo"); } timeEntriesTable.getColumn("overtime").setAggregation( ComponentsHelper.createAggregationInfo( projectsService.getEntityMetaPropertyPath(TimeEntry.class, "overtime"), new TimeEntryOvertimeAggregation())); timeEntriesDs.addCollectionChangeListener(e -> { Multimap<Map<String, Object>, TimeEntry> map = ArrayListMultimap.create(); for (TimeEntry item : timeEntriesDs.getItems()) { Map<String, Object> key = new TreeMap<>(); key.put("user", item.getUser()); key.put("date", item.getDate()); map.put(key, item); } for (Map.Entry<Map<String, Object>, Collection<TimeEntry>> entry : map.asMap().entrySet()) { BigDecimal thisDaysSummary = BigDecimal.ZERO; for (TimeEntry timeEntry : entry.getValue()) { thisDaysSummary = thisDaysSummary.add(timeEntry.getTimeInHours()); } for (TimeEntry timeEntry : entry.getValue()) { BigDecimal planHoursForDay = workdaysTools.isWorkday(timeEntry.getDate()) ? workTimeConfigBean.getWorkHourForDay() : BigDecimal.ZERO; BigDecimal overtime = thisDaysSummary.subtract(planHoursForDay); timeEntry.setOvertimeInHours(overtime); } } }); Date previousMonth = DateUtils.addMonths(timeSource.currentTimestamp(), -1); dateFrom.setValue(DateUtils.truncate(previousMonth, Calendar.MONTH)); dateTo.setValue(DateUtils.addDays(DateUtils.truncate(timeSource.currentTimestamp(), Calendar.MONTH), -1)); approve.addAction(new AbstractAction("approveAll") { @Override public void actionPerform(Component component) { setStatus(timeEntriesDs.getItems(), TimeEntryStatus.APPROVED); } }); approve.addAction(new AbstractAction("approveSelected") { @Override public void actionPerform(Component component) { setStatus(timeEntriesTable.getSelected(), TimeEntryStatus.APPROVED); } }); reject.addAction(new AbstractAction("rejectAll") { @Override public void actionPerform(Component component) { setStatus(timeEntriesDs.getItems(), TimeEntryStatus.REJECTED); } }); reject.addAction(new AbstractAction("rejectSelected") { @Override public void actionPerform(Component component) { setStatus(timeEntriesTable.getSelected(), TimeEntryStatus.REJECTED); } }); status.setOptionsList(Arrays.asList(TimeEntryStatus.values())); user.setOptionsList(projectsService.getManagedUsers(userSession.getCurrentOrSubstitutedUser(), View.MINIMAL)); } protected void setStatus(final Collection<TimeEntry> timeEntries, final TimeEntryStatus timeEntryStatus) { showOptionDialog(getMessage("notification.confirmation"), getMessage("notification.confirmationText"), MessageType.CONFIRMATION, new Action[]{ new DialogAction(DialogAction.Type.YES) { @Override public void actionPerform(Component component) { super.actionPerform(component); for (TimeEntry timeEntry : timeEntries) { timeEntry.setStatus(timeEntryStatus); } getDsContext().commit(); } }, new DialogAction(DialogAction.Type.NO) }); } }