org.projectforge.web.fibu.AuftragEditForm.java Source code

Java tutorial

Introduction

Here is the source code for org.projectforge.web.fibu.AuftragEditForm.java

Source

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2013 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.web.fibu;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.convert.IConverter;
import org.projectforge.common.NumberHelper;
import org.projectforge.common.StringHelper;
import org.projectforge.core.CurrencyFormatter;
import org.projectforge.fibu.AuftragDO;
import org.projectforge.fibu.AuftragsPositionDO;
import org.projectforge.fibu.AuftragsPositionsArt;
import org.projectforge.fibu.AuftragsPositionsStatus;
import org.projectforge.fibu.AuftragsStatus;
import org.projectforge.fibu.KundeDO;
import org.projectforge.fibu.ProjektDO;
import org.projectforge.fibu.RechnungCache;
import org.projectforge.fibu.RechnungDao;
import org.projectforge.fibu.RechnungsPositionVO;
import org.projectforge.task.TaskDO;
import org.projectforge.user.PFUserDO;
import org.projectforge.user.UserGroupCache;
import org.projectforge.web.task.TaskSelectPanel;
import org.projectforge.web.user.UserSelectPanel;
import org.projectforge.web.wicket.AbstractEditForm;
import org.projectforge.web.wicket.AbstractUnsecureBasePage;
import org.projectforge.web.wicket.WicketUtils;
import org.projectforge.web.wicket.bootstrap.GridBuilder;
import org.projectforge.web.wicket.bootstrap.GridSize;
import org.projectforge.web.wicket.components.DatePanel;
import org.projectforge.web.wicket.components.DatePanelSettings;
import org.projectforge.web.wicket.components.LabelValueChoiceRenderer;
import org.projectforge.web.wicket.components.MaxLengthTextArea;
import org.projectforge.web.wicket.components.MaxLengthTextField;
import org.projectforge.web.wicket.components.MinMaxNumberField;
import org.projectforge.web.wicket.components.RequiredMaxLengthTextField;
import org.projectforge.web.wicket.components.SingleButtonPanel;
import org.projectforge.web.wicket.converter.CurrencyConverter;
import org.projectforge.web.wicket.flowlayout.CheckBoxPanel;
import org.projectforge.web.wicket.flowlayout.DivPanel;
import org.projectforge.web.wicket.flowlayout.DivTextPanel;
import org.projectforge.web.wicket.flowlayout.FieldsetPanel;
import org.projectforge.web.wicket.flowlayout.InputPanel;
import org.projectforge.web.wicket.flowlayout.TextAreaPanel;
import org.projectforge.web.wicket.flowlayout.TextStyle;
import org.projectforge.web.wicket.flowlayout.ToggleContainerPanel;
import org.projectforge.web.wicket.flowlayout.ToggleContainerPanel.ToggleStatus;

public class AuftragEditForm extends AbstractEditForm<AuftragDO, AuftragEditPage> {
    private static final long serialVersionUID = 3150725003240437752L;

    private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(AuftragEditForm.class);

    private static final BigDecimal MAX_PERSON_DAYS = new BigDecimal(10000);

    private boolean sendEMailNotification = true;

    @SpringBean(name = "userGroupCache")
    private UserGroupCache userGroupCache;

    protected CheckBox sendEMailNotficationCheckBox;

    protected RepeatingView positionsRepeater;

    protected CustomerSelectPanel kundeSelectPanel;

    private final List<Component> ajaxUpdateComponents = new ArrayList<Component>();

    @SpringBean(name = "rechnungCache")
    private RechnungCache rechnungCache;

    public AuftragEditForm(final AuftragEditPage parentPage, final AuftragDO data) {
        super(parentPage, data);
    }

    public boolean isSendEMailNotification() {
        return sendEMailNotification;
    }

    public void setSendEMailNotification(final boolean sendEMailNotification) {
        this.sendEMailNotification = sendEMailNotification;
    }

    @Override
    @SuppressWarnings("serial")
    protected void init() {
        super.init();
        /* GRID8 - BLOCK */
        gridBuilder.newSplitPanel(GridSize.COL50);
        {
            // Number
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("fibu.auftrag.nummer"));
            final MinMaxNumberField<Integer> number = new MinMaxNumberField<Integer>(InputPanel.WICKET_ID,
                    new PropertyModel<Integer>(data, "nummer"), 0, 99999999);
            number.setMaxLength(8).add(AttributeModifier.append("style", "width: 6em !important;"));
            fs.add(number);
            if (NumberHelper.greaterZero(getData().getNummer()) == false) {
                fs.addHelpIcon(getString("fibu.tooltip.nummerWirdAutomatischVergeben"));
            }
        }
        gridBuilder.newSplitPanel(GridSize.COL50);
        {
            // Net sum
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("fibu.auftrag.nettoSumme"));
            final DivTextPanel netPanel = new DivTextPanel(fs.newChildId(), new Model<String>() {
                @Override
                public String getObject() {
                    return CurrencyFormatter.format(data.getNettoSumme());
                }
            }, TextStyle.FORM_TEXT);
            fs.add(netPanel);
            fs.supressLabelForWarning();
            ajaxUpdateComponents.add(netPanel.getLabel4Ajax());
        }
        gridBuilder.newGridPanel();
        {
            // Title
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("fibu.auftrag.titel"));
            final MaxLengthTextField subject = new RequiredMaxLengthTextField(InputPanel.WICKET_ID,
                    new PropertyModel<String>(data, "titel"));
            subject.add(WicketUtils.setFocus());
            fs.add(subject);
        }
        gridBuilder.newSplitPanel(GridSize.COL50);
        {
            // reference
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("fibu.common.reference"));
            fs.add(new MaxLengthTextField(InputPanel.WICKET_ID, new PropertyModel<String>(data, "referenz")));
        }
        gridBuilder.newSplitPanel(GridSize.COL50);
        {
            // DropDownChoice status
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("status"));
            final LabelValueChoiceRenderer<AuftragsStatus> statusChoiceRenderer = new LabelValueChoiceRenderer<AuftragsStatus>(
                    this, AuftragsStatus.values());
            final DropDownChoice<AuftragsStatus> statusChoice = new DropDownChoice<AuftragsStatus>(
                    fs.getDropDownChoiceId(), new PropertyModel<AuftragsStatus>(data, "auftragsStatus"),
                    statusChoiceRenderer.getValues(), statusChoiceRenderer);
            statusChoice.setNullValid(false).setRequired(true);
            fs.add(statusChoice);
        }
        gridBuilder.newGridPanel();
        {
            // project
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("fibu.projekt")).supressLabelForWarning();
            final ProjektSelectPanel projektSelectPanel = new ProjektSelectPanel(fs.newChildId(),
                    new PropertyModel<ProjektDO>(data, "projekt"), parentPage, "projektId");
            fs.add(projektSelectPanel);
            projektSelectPanel.init();
        }
        {
            // customer
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("fibu.kunde")).supressLabelForWarning();
            kundeSelectPanel = new CustomerSelectPanel(fs.newChildId(), new PropertyModel<KundeDO>(data, "kunde"),
                    new PropertyModel<String>(data, "kundeText"), parentPage, "kundeId");
            fs.add(kundeSelectPanel);
            kundeSelectPanel.init();
            fs.addHelpIcon(getString("fibu.auftrag.hint.kannVonProjektKundenAbweichen"));
        }
        gridBuilder.newSplitPanel(GridSize.COL50);
        {
            // date
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("fibu.auftrag.datum"));
            final DatePanel angebotsDatumPanel = new DatePanel(fs.newChildId(),
                    new PropertyModel<Date>(data, "angebotsDatum"),
                    DatePanelSettings.get().withTargetType(java.sql.Date.class));
            angebotsDatumPanel.setRequired(true);
            fs.add(angebotsDatumPanel);
        }
        gridBuilder.newSplitPanel(GridSize.COL50);
        {
            // Bindungsfrist
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("fibu.auftrag.bindungsFrist"));
            final DatePanel bindungsFristPanel = new DatePanel(fs.newChildId(),
                    new PropertyModel<Date>(data, "bindungsFrist"),
                    DatePanelSettings.get().withTargetType(java.sql.Date.class));
            fs.add(bindungsFristPanel);
        }
        gridBuilder.newSplitPanel(GridSize.COL50);
        {
            // contact person
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("contactPerson"));
            final UserSelectPanel contactPersonSelectPanel = new UserSelectPanel(fs.newChildId(),
                    new PropertyModel<PFUserDO>(data, "contactPerson"), parentPage, "contactPersonId");
            contactPersonSelectPanel.setRequired(true);
            fs.add(contactPersonSelectPanel);
            contactPersonSelectPanel.init();
        }
        gridBuilder.newSplitPanel(GridSize.COL50);
        {
            // Beauftragungsdatum
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("fibu.auftrag.beauftragungsdatum"));
            final DatePanel beauftragungsDatumPanel = new DatePanel(fs.newChildId(),
                    new PropertyModel<Date>(data, "beauftragungsDatum"),
                    DatePanelSettings.get().withTargetType(java.sql.Date.class));
            fs.add(beauftragungsDatumPanel);
        }
        gridBuilder.newSplitPanel(GridSize.COL50);
        {
            // comment
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("comment"));
            fs.add(new MaxLengthTextArea(TextAreaPanel.WICKET_ID, new PropertyModel<String>(data, "bemerkung")),
                    true);
        }
        gridBuilder.newSplitPanel(GridSize.COL50);
        {
            // status comment
            final FieldsetPanel fs = gridBuilder.newFieldset(getString("fibu.auftrag.statusBeschreibung"));
            fs.add(new MaxLengthTextArea(TextAreaPanel.WICKET_ID,
                    new PropertyModel<String>(data, "statusBeschreibung")), true);
        }
        gridBuilder.newGridPanel();
        positionsRepeater = gridBuilder.newRepeatingView();
        refresh();
        if (getBaseDao().hasInsertAccess(getUser()) == true) {
            final DivPanel panel = gridBuilder.newGridPanel().getPanel();
            final Button addPositionButton = new Button(SingleButtonPanel.WICKET_ID) {
                @Override
                public final void onSubmit() {
                    getData().addPosition(new AuftragsPositionDO());
                    refresh();
                }
            };
            final SingleButtonPanel addPositionButtonPanel = new SingleButtonPanel(panel.newChildId(),
                    addPositionButton, getString("add"));
            addPositionButtonPanel.setTooltip(getString("fibu.auftrag.tooltip.addPosition"));
            panel.add(addPositionButtonPanel);
        }
        {
            // email
            gridBuilder.newFieldset(getString("email"))
                    .addCheckBox(new PropertyModel<Boolean>(this, "sendEMailNotification"), null)
                    .setTooltip(getString("label.sendEMailNotification"));
        }
    }

    @SuppressWarnings("serial")
    void refresh() {
        positionsRepeater.removeAll();
        if (CollectionUtils.isEmpty(data.getPositionen()) == true) {
            // Ensure that at least one position is available:
            data.addPosition(new AuftragsPositionDO());
        }
        for (final AuftragsPositionDO position : data.getPositionen()) {
            final boolean abgeschlossenUndNichtFakturiert = position
                    .isAbgeschlossenUndNichtVollstaendigFakturiert();
            final ToggleContainerPanel positionsPanel = new ToggleContainerPanel(positionsRepeater.newChildId()) {
                /**
                 * @see org.projectforge.web.wicket.flowlayout.ToggleContainerPanel#wantsOnStatusChangedNotification()
                 */
                @Override
                protected boolean wantsOnStatusChangedNotification() {
                    return true;
                }

                /**
                 * @see org.projectforge.web.wicket.flowlayout.ToggleContainerPanel#onToggleStatusChanged(org.apache.wicket.ajax.AjaxRequestTarget,
                 *      boolean)
                 */
                @Override
                protected void onToggleStatusChanged(final AjaxRequestTarget target,
                        final ToggleStatus toggleStatus) {
                    if (toggleStatus == ToggleStatus.OPENED) {
                        data.getUiStatus().openPosition(position.getNumber());
                    } else {
                        data.getUiStatus().closePosition(position.getNumber());
                    }
                    setHeading(getPositionHeading(position, this));
                }
            };
            if (position.isAbgeschlossenUndNichtVollstaendigFakturiert()) {
                positionsPanel.setHighlightedHeader();
            }
            positionsRepeater.add(positionsPanel);
            if (data.getUiStatus().isClosed(position.getNumber()) == true) {
                positionsPanel.setClosed();
            } else {
                positionsPanel.setOpen();
            }
            positionsPanel.setHeading(getPositionHeading(position, positionsPanel));

            final GridBuilder posGridBuilder = positionsPanel.createGridBuilder();
            posGridBuilder.newGridPanel();
            {
                final FieldsetPanel fs = posGridBuilder.newFieldset(getString("fibu.auftrag.titel"));
                fs.add(new MaxLengthTextField(InputPanel.WICKET_ID, new PropertyModel<String>(position, "titel")));
            }
            posGridBuilder.newSplitPanel(GridSize.COL33);
            {
                // DropDownChoice type
                final FieldsetPanel fs = posGridBuilder.newFieldset(getString("fibu.auftrag.position.art"));
                final LabelValueChoiceRenderer<AuftragsPositionsArt> artChoiceRenderer = new LabelValueChoiceRenderer<AuftragsPositionsArt>(
                        fs, AuftragsPositionsArt.values());
                final DropDownChoice<AuftragsPositionsArt> artChoice = new DropDownChoice<AuftragsPositionsArt>(
                        fs.getDropDownChoiceId(), new PropertyModel<AuftragsPositionsArt>(position, "art"),
                        artChoiceRenderer.getValues(), artChoiceRenderer);
                artChoice.setNullValid(false);
                artChoice.setRequired(true);
                fs.add(artChoice);
            }
            posGridBuilder.newSplitPanel(GridSize.COL33);
            {
                // Person days
                final FieldsetPanel fs = posGridBuilder.newFieldset(getString("projectmanagement.personDays"));
                fs.add(new MinMaxNumberField<BigDecimal>(InputPanel.WICKET_ID,
                        new PropertyModel<BigDecimal>(position, "personDays"), BigDecimal.ZERO, MAX_PERSON_DAYS));
            }
            posGridBuilder.newSplitPanel(GridSize.COL33);
            {
                // Net sum
                final FieldsetPanel fs = posGridBuilder.newFieldset(getString("fibu.auftrag.nettoSumme"));
                fs.add(new TextField<String>(InputPanel.WICKET_ID,
                        new PropertyModel<String>(position, "nettoSumme")) {
                    @SuppressWarnings({ "rawtypes", "unchecked" })
                    @Override
                    public IConverter getConverter(final Class type) {
                        return new CurrencyConverter();
                    }
                });
                if (abgeschlossenUndNichtFakturiert == true) {
                    fs.setWarningBackground();
                }
            }
            posGridBuilder.newSplitPanel(GridSize.COL33);
            final Set<RechnungsPositionVO> orderPositions = rechnungCache
                    .getRechnungsPositionVOSetByAuftragsPositionId(position.getId());
            final boolean showInvoices = CollectionUtils.isNotEmpty(orderPositions);
            {
                // Invoices
                final FieldsetPanel fs = posGridBuilder.newFieldset(getString("fibu.rechnungen"))
                        .supressLabelForWarning();
                if (showInvoices == true) {
                    final InvoicePositionsPanel panel = new InvoicePositionsPanel(fs.newChildId());
                    fs.add(panel);
                    panel.init(orderPositions);
                } else {
                    fs.add(AbstractUnsecureBasePage.createInvisibleDummyComponent(fs.newChildId()));
                }
            }
            posGridBuilder.newSplitPanel(GridSize.COL33);
            {
                // invoiced
                final FieldsetPanel fs = posGridBuilder.newFieldset(getString("fibu.fakturiert"))
                        .supressLabelForWarning();
                if (showInvoices == true) {
                    fs.add(new DivTextPanel(fs.newChildId(),
                            CurrencyFormatter.format(RechnungDao.getNettoSumme(orderPositions))));
                } else {
                    fs.add(AbstractUnsecureBasePage.createInvisibleDummyComponent(fs.newChildId()));
                }
                if (userGroupCache.isUserMemberOfFinanceGroup() == true) {
                    final DivPanel checkBoxDiv = fs.addNewCheckBoxDiv();
                    checkBoxDiv.add(new CheckBoxPanel(checkBoxDiv.newChildId(),
                            new PropertyModel<Boolean>(position, "vollstaendigFakturiert"),
                            getString("fibu.auftrag.vollstaendigFakturiert")));
                }
            }
            posGridBuilder.newSplitPanel(GridSize.COL33);
            {
                // DropDownChoice status
                final FieldsetPanel fs = posGridBuilder.newFieldset(getString("status"));
                final LabelValueChoiceRenderer<AuftragsPositionsStatus> statusChoiceRenderer = new LabelValueChoiceRenderer<AuftragsPositionsStatus>(
                        fs, AuftragsPositionsStatus.values());
                final DropDownChoice<AuftragsPositionsStatus> statusChoice = new DropDownChoice<AuftragsPositionsStatus>(
                        fs.getDropDownChoiceId(), new PropertyModel<AuftragsPositionsStatus>(position, "status"),
                        statusChoiceRenderer.getValues(), statusChoiceRenderer);
                statusChoice.setNullValid(true);
                statusChoice.setRequired(false);
                fs.add(statusChoice);
                if (abgeschlossenUndNichtFakturiert == true) {
                    fs.setWarningBackground();
                }
            }
            posGridBuilder.newGridPanel();
            {
                // Task
                final FieldsetPanel fs = posGridBuilder.newFieldset(getString("task"));
                final TaskSelectPanel taskSelectPanel = new TaskSelectPanel(fs.newChildId(),
                        new PropertyModel<TaskDO>(position, "task"), parentPage, "taskId:" + position.getNumber()) {
                    @Override
                    protected void selectTask(final TaskDO task) {
                        super.selectTask(task);
                        parentPage.getBaseDao().setTask(position, task.getId());
                    }
                };
                fs.add(taskSelectPanel);
                taskSelectPanel.init();
            }
            {
                // Comment
                final FieldsetPanel fs = posGridBuilder.newFieldset(getString("comment"));
                fs.add(new MaxLengthTextArea(TextAreaPanel.WICKET_ID,
                        new PropertyModel<String>(position, "bemerkung")));
            }
        }
    }

    protected String getPositionHeading(final AuftragsPositionDO position,
            final ToggleContainerPanel positionsPanel) {
        if (positionsPanel.getToggleStatus() == ToggleStatus.OPENED) {
            return getString("label.position.short") + " #" + position.getNumber();
        }
        final StringBuffer heading = new StringBuffer();
        heading.append(escapeHtml(getString("label.position.short"))).append(" #").append(position.getNumber());
        heading.append(": ").append(CurrencyFormatter.format(position.getNettoSumme()));
        if (position.getStatus() != null) {
            heading.append(", ").append(getString(position.getStatus().getI18nKey()));
        }
        if (position.isVollstaendigFakturiert() == false) {
            heading.append(" (").append(getString("fibu.fakturiert.not")).append(")");
        }
        if (StringHelper.isNotBlank(position.getTitel()) == true) {
            heading.append(": ").append(StringUtils.abbreviate(position.getTitel(), 80));
        }
        return heading.toString();
    }

    @Override
    protected Logger getLogger() {
        return log;
    }
}