/* * Copyright (C) 2014 GG-Net GmbH - Oliver Günther * * This program 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, either version 3 of the License, or * (at your option) any later version. * * This program 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 eu.ggnet.dwoss.redtape.document; import java.awt.*; import java.util.List; import javax.swing.*; import eu.ggnet.dwoss.customer.api.CustomerService; import eu.ggnet.dwoss.mandator.MandatorSupporter; import eu.ggnet.dwoss.redtape.*; import eu.ggnet.dwoss.redtape.RedTapeWorker.Addresses; import eu.ggnet.dwoss.redtape.entity.*; import eu.ggnet.dwoss.redtape.position.*; import eu.ggnet.dwoss.rules.DocumentType; import eu.ggnet.dwoss.rules.PositionType; import eu.ggnet.dwoss.util.*; import eu.ggnet.saft.core.*; import static eu.ggnet.dwoss.rules.PositionType.PRODUCT_BATCH; import static eu.ggnet.dwoss.rules.PositionType.UNIT; import static eu.ggnet.saft.core.Client.lookup; /** * * @author pascal.perau */ public class DocumentUpdateController { private final DocumentUpdateView view; private final Window parent; private final Document document; public DocumentUpdateController(DocumentUpdateView view, Document model) { this.view = view; this.document = model; this.parent = SwingUtilities.getWindowAncestor(view); } /** * This method creates a position from a specified type. * Values set to Position are:<br /> * <p/> * @param dossierId the dossier id * @param type the position type * @param refurbishId the refurbishId if a type is unit. * @param forceAdd passed to the unit creation to force conditioned behaviour * ({@link DocumentUpdateController#createUnitPostion(long, java.lang.String, boolean force)}) * @throws eu.ggnet.dwoss.util.UserInfoException */ public void addPosition(long dossierId, PositionType type, String refurbishId, boolean forceAdd) throws UserInfoException { switch (type) { case UNIT: List<Position> result = lookup(UnitOverseer.class) .createUnitPosition(refurbishId, document.getId()).request(new SwingInteraction(view)); for (Position p : result) { if ( p.getType() == UNIT ) lookup(UnitOverseer.class).lockStockUnit(dossierId, p.getRefurbishedId()); } document.appendAll(result); break; case SERVICE: document.append(createServicePosition()); break; case PRODUCT_BATCH: SalesProduct pb = createProductBatchPosition(lookup(RedTapeAgent.class).findAll(SalesProduct.class)); if ( pb != null ) { Position p = new PositionBuilder().setType(type).setDescription(pb.getDescription()). setName(pb.getName()).setUniqueUnitProductId(pb.getUniqueUnitProductId()).createPosition(); p.setPrice((pb.getPrice() == null) ? 0. : pb.getPrice()); p.setBookingAccount(Client.lookup(MandatorSupporter.class).loadPostLedger().get(p.getType()).orElse(-1)); document.append(editPosition(p)); } break; case COMMENT: document.append(createCommentPosition()); break; case SHIPPING_COST: ShippingCostHelper.modifyOrAddShippingCost(document, lookup(CustomerService.class).asCustomerMetaData(view.getCustomerId()).getShippingCondition()); break; } } /** * Edit a Position. * <p/> * @param pos the Position * @return the updated Position. */ public Position editPosition(final Position pos) { try { // Hint: Unusual usage, but works if we need a return type and use null for cancel. return Ui.parent(view).call(() -> pos).choiceSwing(PositionUpdateCask.class).onOk(x -> x.getPosition()).call(); } catch (Exception ex) { UiCore.handle(ex); return null; } // // PositionUpdateCask productUpdateView = new PositionUpdateCask(pos); // OkCancelDialog<PositionUpdateCask> dialog = new OkCancelDialog<>(parent, Dialog.ModalityType.DOCUMENT_MODAL, "Position bearbeiten", productUpdateView); // dialog.setLocationRelativeTo(view); // dialog.setVisible(true); // if ( dialog.getCloseType() == CloseType.OK ) { // Position result = productUpdateView.getPosition(); // return result; // } // return null; } public eu.ggnet.dwoss.redtape.entity.Position createCommentPosition() { eu.ggnet.dwoss.redtape.entity.Position p = new PositionBuilder().setType(PositionType.COMMENT).createPosition(); CommentCreateCask commentView = new CommentCreateCask(p); OkCancelDialog<CommentCreateCask> dialog = new OkCancelDialog<>(parent, Dialog.ModalityType.DOCUMENT_MODAL, "Comment hinzufügen", commentView); dialog.setLocationRelativeTo(view); dialog.setVisible(true); if ( dialog.getCloseType() == CloseType.OK ) { p = commentView.getPosition(); return p; } return null; } public Position createServicePosition() { try { // Hint: Unusual usage, but works if we need a return type and use null for cancel. return Ui.parent(view).call(() -> Position.builder().type(PositionType.SERVICE).build()) .choiceSwing(ServiceViewCask.class).onOk(x -> x.getPosition()).call(); } catch (Exception ex) { UiCore.handle(ex); return null; } // .ggnet.dwoss.redtape.entity.Position p = new PositionBuilder().setType(PositionType.SERVICE).createPosition(); // ServiceViewCask serviceView = new ServiceViewCask(p); // OkCancelDialog<ServiceViewCask> dialog = new OkCancelDialog<>(parent, Dialog.ModalityType.DOCUMENT_MODAL, "Diensleistung/Kleinteil hinzufügen", serviceView); // dialog.setLocationRelativeTo(view); // dialog.setVisible(true); // if ( dialog.getCloseType() == CloseType.OK ) { // p = serviceView.getPosition(); // return p; // } // return null; } public SalesProduct createProductBatchPosition(List<SalesProduct> products) { SalesProductChooserCask spcView = new SalesProductChooserCask(products); OkCancelDialog<SalesProductChooserCask> dialog = new OkCancelDialog<>(parent, Dialog.ModalityType.DOCUMENT_MODAL, "Artikel hinzufügen", spcView); dialog.setLocationRelativeTo(view); dialog.setVisible(true); if ( dialog.getCloseType() == CloseType.OK ) { return spcView.getProduct(); } return null; } public void editDocumentInvoiceAddress() { if ( view.getCustomerId() <= 0 ) { JOptionPane.showMessageDialog(view, "Ein Kunde muss ausgewählt sein."); return; } DocumentAdressUpdateView dauv = new DocumentAdressUpdateView(view.getCustomerId(), document.getInvoiceAddress().getDescription(), true); OkCancelDialog<DocumentAdressUpdateView> dialog = new OkCancelDialog<>(parent, Dialog.ModalityType.DOCUMENT_MODAL, "Adressen ändern", dauv); dialog.setLocationRelativeTo(view); dialog.setVisible(true); if ( dialog.getCloseType() == CloseType.OK ) { if ( document.getInvoiceAddress() == document.getShippingAddress() ) { document.setInvoiceAddress(lookup(RedTapeWorker.class).requestAddressByDescription(dauv.getAddress())); document.setShippingAddress(document.getInvoiceAddress()); } document.setInvoiceAddress(lookup(RedTapeWorker.class).requestAddressByDescription(dauv.getAddress())); view.refreshAddressArea(); } } public void editDocumentShippingAddress() { if ( view.getCustomerId() <= 0 ) { JOptionPane.showMessageDialog(view, "Ein Kunde muss ausgewählt sein."); return; } DocumentAdressUpdateView dauv = new DocumentAdressUpdateView(view.getCustomerId(), document.getShippingAddress().getDescription(), false); OkCancelDialog<DocumentAdressUpdateView> dialog = new OkCancelDialog<>(parent, Dialog.ModalityType.DOCUMENT_MODAL, "Adressen ändern", dauv); dialog.setLocationRelativeTo(view); dialog.setVisible(true); if ( dialog.getCloseType() == CloseType.OK ) { document.setShippingAddress(lookup(RedTapeWorker.class).requestAddressByDescription(dauv.getAddress())); view.refreshAddressArea(); } } public void resetAddressesToCustomerData() { if ( view.getCustomerId() <= 0 ) { JOptionPane.showMessageDialog(view, "Ein Kunde muss ausgewählt sein."); return; } Addresses addresses = lookup(RedTapeWorker.class).requestAdressesByCustomer(view.getCustomerId()); document.setInvoiceAddress(addresses.getInvoice()); document.setShippingAddress(addresses.getShipping()); view.refreshAddressArea(); } /** * Asks the User if he/she wants to Recalculate the ShippingCosts. * * @param document * @param shippingCondition * @return weither the shipping costs are recalculated or not. */ boolean optionalRecalcShippingCost() { if ( document.getType() != DocumentType.ORDER && document.getType() != DocumentType.INVOICE ) return true; String msg; String titel; if ( document.getPositions().size() == 1 && document.containsPositionType(PositionType.SHIPPING_COST) ) { JOptionPane.showMessageDialog(parent, "Der Vorgang enthält nur Versandkosten.", "Nur Versandkosten?", JOptionPane.INFORMATION_MESSAGE); return false; } else if ( document.getDossier().isDispatch() ) { msg = "Sie haben einen Versandauftrag geändert.\nSollen die Versandkosten automatisch berechnet werden?"; titel = "Automatisches Setzten der Versandkosten"; } else if ( !document.getDossier().isDispatch() && document.containsPositionType(PositionType.SHIPPING_COST) ) { msg = "Sie haben einen Abholauftrag, der Versandkosten enthält.\nSollen die Versandkosten entfernt werden?"; titel = "Automatisches entfernen der Versandkosten"; } else { return true; } int confirmDialog = JOptionPane.showConfirmDialog(parent, msg, titel, JOptionPane.YES_NO_CANCEL_OPTION); switch (confirmDialog) { case JOptionPane.CANCEL_OPTION: return false; case JOptionPane.YES_OPTION: if ( document.getDossier().isDispatch() ) { ShippingCostHelper.modifyOrAddShippingCost(document, lookup(CustomerService.class).asCustomerMetaData(view.getCustomerId()).getShippingCondition()); } else { ShippingCostHelper.removeShippingCost(document); } case JOptionPane.NO_OPTION: default: return true; } } }