package com.gpc.tams.handler.cartmanagement; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.ArrayUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import com.gpc.tams.enums.invoice.FulfillmentTypeEnum; import com.gpc.tams.enums.log.LogName; import com.gpc.tams.handler.BaseHandler; import com.gpc.tams.model.CustomerDTO; import com.gpc.tams.model.common.ActionDTO; import com.gpc.tams.model.common.Session; import com.gpc.tams.model.invoice.InvoiceHeader; import com.gpc.tams.model.invoice.InvoiceLineItemDTO; import com.gpc.tams.model.invoice.InvoiceNoteDTO; import com.gpc.tams.model.invoice.LineItem; import com.gpc.tams.model.invoice.LineItem.Type; import com.gpc.tams.model.request.InvoiceRequest; import com.gpc.tams.model.request.MetaData; import com.gpc.tams.model.response.InvoiceResponse; import com.gpc.tams.model.response.NonCanonicalResponse; import com.gpc.tams.profile.Profile; import com.gpc.tams.repository.RefRemoteSystem; import com.gpc.tams.repository.common.StoreProfile; import com.gpc.tams.util.DefaultUtil; import com.gpc.tams.util.invoice.InvoiceUtil; /** * The handler class for managing cart between multiple clients. All clients will communicate here. * The cart managed has version available. The cart reader in respective clients can compare the cart * version they have and cart version this cart returns. If they don't see any difference they can * ignore any kind of update. But if they see a change they can navigate to individual line and * check for the line version change. * */ @Service public class CartHandler extends BaseHandler, InvoiceHeader, InvoiceHeader, LineItem, LineItem>{ @Value("${MAX_CART_INACTIVE_TIME}")private long MAX_INACTIVE_TIME; private static final long CLEANUP_INTERVAL = 1 * 60 * 1000; /** * We want to keep the json ordered to help manipulation of child items if required. */ protected static final ComparatorlineSorter = new Comparator() { public int compare(final LineItem firstLine, LineItem secondLine) { return DefaultUtil.getInt(firstLine.getSequence()) - DefaultUtil.getInt(secondLine.getSequence()); } }; protected static final ComparatorlineSorterAddFirst = new Comparator() { public int compare(final LineItem firstLine, LineItem secondLine) { if(firstLine.getSequence() == null){ return -1; } else if(secondLine.getSequence() == null){ return 1; } else { return firstLine.getSequence() - secondLine.getSequence(); } } }; /** * A place holder to contain two form of cart. * Rationale behind it: * TAMS generates lots of data related to cart in client not in server. * Hence it is impossible for us to render a response with all updated values * to other applications like PPSE2 and NAPA Xpress. * * This design will ensure that we keep cart related to TAMS and other applications separate. * Any request coming in operate on the TAMS version of cart. Then once data is processed through * TAMS, we push that information to other version of cart. * */ private static class CartHolder{ InvoiceHeader cartForExternalApplication; InvoiceHeader cartForTAMS; long externalId; CartHolder(final InvoiceHeader cartForTAMS, final InvoiceHeader cartForExternalApplication){ this.cartForExternalApplication = cartForExternalApplication; this.cartForTAMS = cartForTAMS; } CartHolder(final InvoiceHeader cartForTAMS, final InvoiceHeader cartForExternalApplication, final long externalId){ this(cartForTAMS, cartForExternalApplication); this.externalId = externalId; } long incrementExternalId(){ return ++externalId; } } /** * We are using a synchronizedMap to keep the integrity of map intact. Simultaneously multiple * threads are going to access this map. Even though we are using a synchronizedMap, we are still * operating the logic inside synchronized block as an second layer of safety. */ private Map sessionToCart = Collections.synchronizedMap(new HashMap()); protected void loadProfiles(InvoiceRequest request) { final Profile profiles = new Profile(); final StoreProfile storeProfile = new StoreProfile(){ public String getLanguageCode() { return "EN"; } public String getCountryCode() { return "US"; } }; profiles.setStoreProfile(storeProfile); request.getInformation().setProfile(profiles); } /* (non-Javadoc) * @see com.gpc.tams.handler.BaseHandler#addRequiredFields * We do some prep work in the data received so that it turns into workable set of data for * the actual logic. */ @Override protected void addRequiredFields(InvoiceRequest request, NonCanonicalResponse response) { if(request.isValid()){ final ActionDTO action = request.getAction(); if((DefaultUtil.getBoolean(action.isCreate()) || DefaultUtil.getBoolean(action.isEdit())) && RefRemoteSystem.fromAlias(request.getSourceSystem()) == RefRemoteSystem.TAMS){ final InvoiceHeader cart = request.getInvoiceHeader(); if(cart != null){ final CustomerDTO customer = cart.getCustomer(); if(customer != null){ try{ /* * Just a hack. * TAMSII client is not equipped to do string encoding with specific * encoding style. But it needs to pass the encoded value to other * applications. Hence we are doing it here. * * Hard coding "UTF-8". * Not sure if I need to use any property here. * I am just thinking "UTF-8" must be good for a good amount of time. * Hence I am not going through the extra steps of defining and * reading from property. */ customer.setCustomerName(URLEncoder.encode(customer.getCustomerName(), "UTF-8")); }catch(Exception exception){ /* * If something happens, we are logging the error and continuing as this * is not such a critical component. Later the cause of error can be * analyzed. */ context.logError(exception.getMessage()); } } } } final Boolean isAddRequest = DefaultUtil.getBoolean(action.isAdd()); final LineItem[]items = request.getInvoiceLineItems(); if(items != null){ Arrays.sort(items, lineSorter); for(final LineItem item : items){ if(item.getVersion() == null){ item.setVersion(1); } if(isAddRequest) { if (RefRemoteSystem.fromAlias(request.getSourceSystem()) == RefRemoteSystem.TAMS) { item.setSequence((Integer) item.get("lineItemId")); item.setGeneratedBySequence((Integer) item.get("generatedByLineItemId")); item.setGeneratedByLineItem(InvoiceUtil.getLineItemByGeneratedBySequence(items, item.getGeneratedBySequence())); } else { //TODO We may not always get generatedByLineId possible to get converted into Integer. String generatedByLineItemId = (item.get("generatedByLineItemId") != null)? item.get("generatedByLineItemId").toString():null; item.setGeneratedByLineItem(InvoiceUtil.getLineItemByGeneratedByLineItemId(items, generatedByLineItemId)); final LineItem parentItem = item.getGeneratedByLineItem(); if(item.getType() == Type.LINE && ((InvoiceLineItemDTO)item).getFulfillmentType() == FulfillmentTypeEnum.DIRECT_SHIP_ORDERED){ item.setGeneratedBySequence(Integer.valueOf(generatedByLineItemId)); } if (item.getType() == Type.NOTE && RefRemoteSystem .fromAlias(request.getSourceSystem()) == RefRemoteSystem.NAPA_XPRESS && generatedByLineItemId != null) { if(parentItem == null || !(parentItem.getType() == Type.LINE && ((InvoiceLineItemDTO)parentItem).getFulfillmentType() == FulfillmentTypeEnum.DIRECT_SHIP_ORDERED)){ item.setGeneratedBySequence(Integer.valueOf(generatedByLineItemId)); } } } } else { item.setGeneratedByLineItem(InvoiceUtil.getLineItemByGeneratedBySequence(items, item.getGeneratedBySequence())); } } } } } /* (non-Javadoc) * @see com.gpc.tams.handler.BaseHandler#isFileActivityRequired */ protected boolean isFileActivityRequired(InvoiceRequest request) { return false; } /* (non-Javadoc) * @see com.gpc.tams.handler.BaseHandler#delegateHandle * Actual logic goes here. We clone the cart before returning as this will * avoid modifying the same instance in post processing logic. */ protected InvoiceHeader delegateHandle(InvoiceRequest request, NonCanonicalResponse response) throws Exception { final ActionDTO action = request.getAction(); synchronized(sessionToCart){ final Session session = new Session(request.getSessionID()); final Boolean isCreateRequest = DefaultUtil.getBoolean(action.isCreate()); final Boolean isValidateRequest = DefaultUtil.getBoolean(action.isValidate()); if(isValidateRequest) { return validate(request.getInvoiceHeader().getSalesOrderNumber(), request); } else if(isCreateRequest){ return createCart(request, session).clone(); } else { final CartHolder cartHolder = sessionToCart.get(session); if(cartHolder == null){ throwBusinessException(300002, LogName.ILLEGAL_STATE, request.getInformation().getProfile(), request.getSessionID()); } final InvoiceHeader cart = cartHolder.cartForTAMS; final Boolean isEraseRequest = DefaultUtil.getBoolean(action.isErase()); if(isEraseRequest){ localTransin2Client.disposeClonedGuiInstance(request.getSessionID()); context.logDebug("EraseRequest: Session ID = "+request.getSessionID()+", Correlation ID = "+request.getCorrelationID()); return sessionToCart.remove(session).cartForTAMS; } else { final Boolean isRefreshRequest = DefaultUtil.getBoolean(action.isRefresh()); if(isRefreshRequest){ refresh(session, request.getInformation()); return cart.clone(); } else { final Boolean isReadRequest = DefaultUtil.getBoolean(action.isRead()); if(isReadRequest){ context.logTrace("ReadRequest: By "+request.getInformation().getSource()+"Session ID = "+request.getSessionID()+", Correlation ID = "+request.getCorrelationID()); if(request.getInformation().getSource() == RefRemoteSystem.TAMS){ refresh(session, request.getInformation()); return cart.clone(); } else { if(request.getInformation().getSource() == RefRemoteSystem.PPSE2) { localTransin2Client.keepAlivePpse2(request.getSessionID()); } return cartHolder.cartForExternalApplication.clone(); } } else { final LinkedListitemsInCart = new LinkedList(); if(cart.getLineItems() != null){ itemsInCart.addAll(Arrays.asList(cart.getLineItems())); } if(DefaultUtil.getBoolean(action.isEdit())){ final String invoiceCreatedForStoreNumber = request.getInvoiceCreatedForStoreNumber(); if(invoiceCreatedForStoreNumber != null){ cart.setCustomer(request.getInvoiceHeader().getCustomer()); } else { final InvoiceHeader newCart = request.getInvoiceHeader(); if(newCart != null){ final CustomerDTO newCustomer = newCart.getCustomer(); cart.setCustomer(newCustomer); } if(request.getInvoiceLineItems() != null){ for(LineItem item : request.getInvoiceLineItems()){ edit(item, itemsInCart, request.getInformation()); } } else { itemsInCart.clear(); } } } else{ for(LineItem item : request.getInvoiceLineItems()){ if(DefaultUtil.getBoolean(action.isAdd())){ context.logDebug("AddToCartRequest: By "+request.getInformation().getSource()+", Session ID = "+request.getSessionID()+", Correlation ID = "+request.getCorrelationID()); add(cartHolder, item, itemsInCart, request.getInformation()); } else if(DefaultUtil.getBoolean(action.isDelete())){ remove(item, itemsInCart, request.getInformation()); } } } cart.incrementNewVersion(); cart.setLineItems(itemsInCart.toArray(new LineItem[itemsInCart.size()])); if(request.getInformation().getSource() == RefRemoteSystem.TAMS){ sessionToCart.put(session, new CartHolder(cart.clone(), cart.clone(), cartHolder.externalId)); } else { sessionToCart.put(session, new CartHolder(cart.clone(), cartHolder.cartForExternalApplication, cartHolder.externalId)); } return cart.clone(); } } } } } } /** * Method to create the cart. * * @param request * @param newSession * @return */ private InvoiceHeader createCart(final InvoiceRequest request, final Session newSession){ final String methodSpec = "[NapaXpress] - CartHandler.createCart - "; context.logTrace(methodSpec); final MetaData information = request.getInformation(); final InvoiceHeader newCart = request.getInvoiceHeader(); final Setkeys = sessionToCart.keySet(); final IteratorkeyIterator = keys.iterator(); while(keyIterator.hasNext()){ final Session session = keyIterator.next(); final InvoiceHeader existingCart = sessionToCart.get(session).cartForTAMS; final long timeRemainingForSessionExpiration = getRemainingTimeForSessionExpiration(session.getLastAccessedTime()); /* * We are first checking if same sales order number is in play. There is a chance of * this happening as we are allowing to split the same sales order in multiple invoices. * Although we are allowing, it is risky to operate on those invoices at the same time. * Hence we throw an error back. If sales order remaining is stale data, system will * cleanup after a set time. The message that we return let the client know about the * time remaining along with who is/was using it. */ if(newCart.getSalesOrderNumber().equals(existingCart.getSalesOrderNumber())){ if(timeRemainingForSessionExpiration > 0){ throwBusinessException(300001, LogName.ILLEGAL_STATE, information.getProfile(), newCart.getSalesOrderNumber(), session.getEmployeeName(), session.getEmployeeNumber(), session.getClientIP(), (timeRemainingForSessionExpiration + 1000) / 1000); } /* * If at this point we happened to have crossed the given stale data allowed time, * we are removing the session from memory and going ahead with creating the cart. * This is really really an edge case scenario. */ sessionToCart.remove(session); break; } /* * We are probably checking once in a million year scenario here. We are throwing back * an error if we find a session with the session id passed in. If the session remaining * is stale data, system will cleanup after a set time. The message that we return let * the client know about the time remaining along with who is/was using it. */ if(session.equals(newSession)){ if(timeRemainingForSessionExpiration > 0){ throwBusinessException(300003, LogName.ILLEGAL_STATE, information.getProfile(), session.getSessionID(), session.getEmployeeName(), session.getEmployeeNumber(), session.getClientIP(), (timeRemainingForSessionExpiration + 1000) / 1000); } /* * If at this point we happened to have crossed the given stale data allowed time, * we are removing the session from memory and going ahead with creating the cart. * This is really really an edge case scenario. */ sessionToCart.remove(session); break; } } newCart.setLineItems(request.getInvoiceLineItems()); newCart.incrementNewVersion(); newSession.setLastAccessedTime(System.currentTimeMillis()); newSession.setEmployeeNumber(request.getEmployeeNumber()); newSession.setEmployeeName(request.getEmployeeName()); newSession.setClientIP(request.getClientIP()); sessionToCart.put(newSession, new CartHolder(newCart.clone(), newCart.clone())); return newCart; } /** * We are refreshing the session from active clients. This will help to remove stale data * remaining on server. This will also allow TAMS to make the buttons enable to launch other * clients browser. * * @param session * @param information */ private void refresh(final Session session, final MetaData information){ final String methodSpec = "[NapaXpress] - CartHandler.refresh - "; context.logTrace(methodSpec); final Setkeys = sessionToCart.keySet(); final IteratorkeyIterator = keys.iterator(); while(keyIterator.hasNext()){ final Session key = keyIterator.next(); if(key.equals(session)){ key.setLastAccessedTime(System.currentTimeMillis()); break; } } } /** * This method will add the line item received in request to cart on server. * * @param itemToBeAdded * @param itemsAlreadyInCart * @param information * @return */ private LineItem add(final CartHolder cartHolder, final LineItem itemToBeAdded, LinkedListitemsAlreadyInCart, final MetaData information){ if(information.getSource() != RefRemoteSystem.TAMS){ final LineItem parent = itemToBeAdded.getGeneratedByLineItem(); if(parent != null){ if(parent.getChilds() == null){ parent.setChilds(new ArrayList()); } parent.getChilds().add(itemToBeAdded); return null; } if(itemToBeAdded.getType() == Type.LINE){ itemToBeAdded.setExternalIdentifier(((InvoiceLineItemDTO)itemToBeAdded).getLineAbbreviation() + "-" + ((InvoiceLineItemDTO)itemToBeAdded).getPartNumber() + "-" + cartHolder.incrementExternalId()); } else if(itemToBeAdded.getType() == Type.NOTE){ itemToBeAdded.setExternalIdentifier("Note - "+String.valueOf(cartHolder.incrementExternalId())); } itemsAlreadyInCart.add(itemToBeAdded); } else { for(int itemIndex = 0; itemIndex < itemsAlreadyInCart.size(); itemIndex++){ final LineItem itemAlreadyInCart = itemsAlreadyInCart.get(itemIndex); if(itemToBeAdded.getExternalIdentifier() != null && itemToBeAdded.getExternalIdentifier().equals(itemAlreadyInCart.getExternalIdentifier())){ itemsAlreadyInCart.remove(itemAlreadyInCart); itemsAlreadyInCart.add(itemToBeAdded); break; } if(itemIndex + 1 == itemsAlreadyInCart.size()){ itemsAlreadyInCart.add(itemToBeAdded); break; } } if(itemsAlreadyInCart.size() == 0){ itemsAlreadyInCart.add(itemToBeAdded); } } return itemToBeAdded; } /** * Editing of line item goes here. Just before editing we do a sanity check of whether we * really need to update by comparing the updatable fields to keep updating the version of * cart unnecessarily. * * @param item * @param itemsAlreadyInCart * @param information * @return */ public LineItem edit(final LineItem item, ListitemsAlreadyInCart, final MetaData information){ final String methodSpec = "[NapaXpress] - CartHandler.edit - "; context.logTrace(methodSpec); LineItem editedItem = null; final Iterator iterator = itemsAlreadyInCart.iterator(); while(iterator.hasNext()){ boolean thisIsTheUpdatedItem = false; final LineItem itemInCart = iterator.next(); if(information.getSource() == RefRemoteSystem.TAMS){ if (itemInCart.getSequence() != null) { thisIsTheUpdatedItem = itemInCart.getSequence().equals(item.getSequence()); } } else { /* * For non-TAMS application, an extra cushion of line and part is added to id while * checking equality. If updated by TAMS, we just check id and trust it. */ thisIsTheUpdatedItem = itemInCart.equals(item); } if(thisIsTheUpdatedItem){ if(itemInCart.getType() == Type.LINE){ final InvoiceLineItemDTO itemToBeEdited = (InvoiceLineItemDTO)itemInCart; final InvoiceLineItemDTO itemReceived = (InvoiceLineItemDTO)item; /* * As much as I hate to check for a source here, I do not find any other * better solution for this. */ if(information.getSource() != RefRemoteSystem.TAMS){ if(itemToBeEdited.getGeneratedBySequence() != null){ throwBusinessException(300004, LogName.PERMISSION_DENIED, information.getProfile()); } /* * We throw a stale data exception if the version we have and version client sends * does not match. Client can take appropriate actions on that. They can most probably * reload the page and start doing their operation on top of that. */ if(!itemInCart.getVersion().equals(item.getVersion())){ throwUpdatingStaleDataException(information.getProfile(), item, itemInCart); } itemToBeEdited.setBilledQuantity(itemReceived.getBilledQuantity()); context.logTrace(methodSpec+" Source = "+information.getSource()+" new Billed Quantity= " +itemReceived.getBilledQuantity()); context.logTrace(methodSpec+" Line Item = "+itemToBeEdited); if (itemReceived.getFulfillmentType() != null) { itemToBeEdited.setFulfillmentType(itemReceived.getFulfillmentType()); } } else { itemToBeEdited.setChilds(null); itemToBeEdited.setLineAbbreviation(itemReceived.getLineAbbreviation()); itemToBeEdited.setPartNumber(itemReceived.getPartNumber()); itemToBeEdited.setPartDescription(itemReceived.getPartDescription()); itemToBeEdited.setGeneratedByLineItem(itemReceived.getGeneratedByLineItem()); itemToBeEdited.setBilledQuantity(itemReceived.getBilledQuantity()); itemToBeEdited.setUnitListPrice(itemReceived.getUnitListPrice()); itemToBeEdited.setUnitPrice(itemReceived.getUnitPrice()); itemToBeEdited.setUnitCost(itemReceived.getUnitCost()); itemToBeEdited.setUnitCoreCost(itemReceived.getUnitCoreCost()); itemToBeEdited.setSpecialOrder(itemReceived.isSpecialOrder()); itemToBeEdited.setFulfillmentType(itemReceived.getFulfillmentType()); itemToBeEdited.setTokenId(itemReceived.getTokenId()); itemToBeEdited.setKitComponent(itemReceived.isKitComponent()); itemToBeEdited.setKitHeader(itemReceived.isKitHeader()); itemToBeEdited.setLineItemOriginID(itemReceived.getLineItemOriginID()); if(!ArrayUtils.isEmpty(itemReceived.getOrderLineItem())) { itemToBeEdited.setOrderLineItem(itemReceived.getOrderLineItem()); itemToBeEdited.setFulfillmentType(FulfillmentTypeEnum.NAPA_XPRESS_ORDERED); } } } else { final InvoiceNoteDTO itemToBeEdited = (InvoiceNoteDTO)itemInCart; final InvoiceNoteDTO itemReceived = (InvoiceNoteDTO)item; itemToBeEdited.setGeneratedByLineItem(itemReceived.getGeneratedByLineItem()); itemToBeEdited.setValue(itemReceived.getValue()); } itemInCart.incrementNewVersion(); editedItem = itemInCart; break; } } /* * This really should not happen, if we don't find the line requested at all, then we are * throwing an error back. Probably client needs to reload their page and sync up correctly * with cart on tams server. */ if(editedItem == null){ throwBusinessException(60013, LogName.DATA_NOT_FOUND, information.getProfile(), "Item"); } return editedItem; } /** * This method returns the cart information based on the sales order number. * * @param salesOrderNumber * @param request * @return InvoiceHeader */ private InvoiceHeader validate(final Long salesOrderNumber, final InvoiceRequest request){ final String methodSpec = "[NapaXpress] - CartHandler.validate - "; context.logTrace(methodSpec); final Setkeys = sessionToCart.keySet(); final IteratorkeyIterator = keys.iterator(); InvoiceHeader invoiceHeader = null; while(keyIterator.hasNext()){ final Session session = keyIterator.next(); final CartHolder cartHolder = sessionToCart.get(session); if(cartHolder == null){ break; } final InvoiceHeader existingCart = cartHolder.cartForTAMS; context.logTrace(methodSpec+"Sales Order Number= "+salesOrderNumber); if(salesOrderNumber.equals(existingCart.getSalesOrderNumber())){ invoiceHeader = existingCart; request.setSessionID(session.getSessionID()); break; } } if (invoiceHeader == null) { throwBusinessException(60013, LogName.DATA_NOT_FOUND, request.getInformation() .getProfile(), "Sales Order"); } return invoiceHeader; } private LineItem remove(final LineItem item, ListitemsAlreadyInCart, final MetaData information){ final String methodSpec = "[NapaXpress] - CartHandler.remove - "; context.logTrace(methodSpec); boolean itemDeleted = false; final Iterator iterator = itemsAlreadyInCart.iterator(); while(iterator.hasNext()){ final LineItem itemInCart = iterator.next(); if(itemInCart.equals(item)){ if(information.getSource() != RefRemoteSystem.TAMS){ if(itemInCart.getGeneratedBySequence() != null){ throwBusinessException(300004, LogName.PERMISSION_DENIED, information.getProfile()); } if(!itemInCart.getVersion().equals(item.getVersion())){ throwUpdatingStaleDataException(information.getProfile(), item, itemInCart); } itemInCart.setMarkedForDeletion(true); itemDeleted = true; } else { itemDeleted = itemsAlreadyInCart.remove(item); } break; } } if(information.getSource() != RefRemoteSystem.TAMS && !itemDeleted){ throwBusinessException(60013, LogName.DATA_NOT_FOUND, information.getProfile(), "Item"); } return item; } /** * Clean up scheduler. */ @Scheduled(fixedDelay=CLEANUP_INTERVAL) public void clearObsoleteSalesOrder() { synchronized(sessionToCart) { final Setkeys = sessionToCart.keySet(); final IteratorkeyIterator = keys.iterator(); while(keyIterator.hasNext()){ final Session key = keyIterator.next(); if(getRemainingTimeForSessionExpiration(key.getLastAccessedTime()) < 0){ sessionToCart.remove(key); } } } } /** * Utility method for getting the time remaining for session expiration. * * @param lastAccessedTime * @return */ private long getRemainingTimeForSessionExpiration(final long lastAccessedTime){ final long timeElapsedSinceLastAccess = System.currentTimeMillis() - lastAccessedTime; final long timeToWaitBeforeCreatingNewCart = MAX_INACTIVE_TIME + CLEANUP_INTERVAL - timeElapsedSinceLastAccess; return timeToWaitBeforeCreatingNewCart; } /* (non-Javadoc) * @see com.gpc.tams.handler.BaseHandler#postProcess * * A framework method for populating the response. */ public void postProcess(InvoiceRequest request, NonCanonicalResponse response, InvoiceHeader invoice) { final InvoiceResponse invoiceResponse = new InvoiceResponse(); invoiceResponse.setSessionID(request.getSessionID()); invoiceResponse.setInvoiceHeader(invoice); response.setResponse(invoiceResponse); } /* (non-Javadoc) * @see com.gpc.tams.handler.BaseHandler#format * * A framework method to format the response as client expects. */ public void format(InvoiceRequest request, NonCanonicalResponse response, final MetaData information) { final InvoiceResponse invoiceResponse = response.getResponse(); if(invoiceResponse == null){ return; } final ActionDTO action = request.getAction(); if(DefaultUtil.getBoolean(action.isRefresh()) || (information.getSource() != RefRemoteSystem.TAMS && !DefaultUtil.getBoolean(action.isRead()))){ invoiceResponse.setInvoiceHeader(null); } else { if(!DefaultUtil.getBoolean(action.isValidate())) { final InvoiceHeader invoiceHeader = invoiceResponse.getInvoiceHeader(); invoiceHeader.setSalesOrderNumber(null); invoiceHeader.setTracking(null); final LineItem[]lines = invoiceHeader.getLineItems(); if(lines != null){ for(final LineItem line : lines){ line.setTracking(null); if(line.getType() == Type.LINE){ final InvoiceLineItemDTO lineItem = (InvoiceLineItemDTO)line; if(request.getInformation().getSource() != RefRemoteSystem.TAMS){ lineItem.setOrderLineItem(null); lineItem.setChilds(null); lineItem.setExternalIdentifier(null); lineItem.setMarkedForDeletion(null); } } else if (line.getType() == Type.NOTE){ final InvoiceNoteDTO note = (InvoiceNoteDTO)line; if(request.getInformation().getSource() != RefRemoteSystem.TAMS){ note.setExternalIdentifier(null); note.setMarkedForDeletion(null); } } } if(information.getSource() == RefRemoteSystem.TAMS && DefaultUtil.getBoolean(action.isRead())){ Arrays.sort(lines, lineSorterAddFirst); } } } } } /* (non-Javadoc) * @see com.gpc.tams.handler.BaseHandler#getProgramSource */ public String getProgramSource() { return ""; } }