public PurchaseSelectTabPanel(String id, final EntitlementLookup entilement) {
      super(id);

      final List<IColumn<Product>> purchaseHistoryColumns = new ArrayList<IColumn<Product>>();

      purchaseHistoryColumns.add(
          new AbstractColumn<Product>(null, "selectLinkColumn") {

            private static final long serialVersionUID = 1L;

            @Override
            public void populateItem(
                Item<ICellPopulator<Product>> cellItem,
                String componentId,
                IModel<Product> rowModel) {
              Product row = (Product) rowModel.getObject();
              cellItem.add(new SelectLinkPanel(componentId, rowModel, row, entilement));
            }
          });

      final PurchaseHistoryDataProvider purchasesDataProvider = new PurchaseHistoryDataProvider();
      DailyRhythmPortalSession session = getDailyRhythmPortalSession();
      purchasesDataProvider.setPurchaseHistoryList(session.getAllPurchaseHistory());

      final AjaxFallbackDefaultDataTable<Product> entitlementPurchasesTable =
          new AjaxFallbackDefaultDataTable<Product>(
              "entitlementPurchasesTable", purchaseHistoryColumns, purchasesDataProvider, 200) {

            private static final long serialVersionUID = 1L;

            @Override
            public boolean isVisible() {
              DailyRhythmPortalSession session = getDailyRhythmPortalSession();
              return session.getAllPurchaseHistory() != null
                  && !session.getAllPurchaseHistory().isEmpty();
            }
          };
      entitlementPurchasesTable.setMarkupId("entitlementPurchasesTable");
      entitlementPurchasesTable.setOutputMarkupId(true);
      entitlementPurchasesTable.setOutputMarkupPlaceholderTag(true);
      add(entitlementPurchasesTable);
    } // End Panel Constructor
  @SuppressWarnings({"rawtypes", "unchecked"})
  public DigitalRecSheetPage(
      Recommendation recommendation, final MobileSalesWorkspacePage mswPage) {
    final DailyRhythmPortalSession drpSession = getDailyRhythmPortalSession();

    if (recommendation == null) {
      recommendation = new Recommendation(); // check for null!
    }
    model = new DigitalRecSheetModel(recommendation);

    final boolean transferToBeast = recommendation.isTransferFlag();

    form.add(
        new Image(
            "transfer-to-beast", new ContextRelativeResource("/css/img/transfer-to-beast.png")) {

          private static final long serialVersionUID = 1L;

          @Override
          public boolean isVisible() {
            return transferToBeast;
          }
        });

    formChanged = false;

    FeedbackPanel feedbackPanel = new FeedbackPanel("feedback");
    feedbackPanel.setOutputMarkupPlaceholderTag(true);
    add(feedbackPanel);

    DrpUser user = drpSession.getDrpUser();

    model.setUser(user);

    // Tools Menu components:
    final ModalWindow coverageCheckModal = new ModalWindow("coverageCheckModal");

    // tools menu links:
    form.add(new BookmarkablePageLink("toolsLink1", CustomerDashboardPage.class));

    AjaxLink alink =
        new AjaxLink("toolsLink2") {

          private static final long serialVersionUID = 1L;

          @Override
          public void onClick(AjaxRequestTarget target) {

            coverageCheckModal.setContent(
                new CoverageCheckPanel(coverageCheckModal.getContentId(), coverageCheckModal));
            coverageCheckModal.show(target);
          }
        };
    add(coverageCheckModal);
    form.add(alink);

    // no-contract coverage maps link.
    AjaxLink ppcmLink =
        new AjaxLink("toolsLink3") {

          private static final long serialVersionUID = 1L;

          @Override
          public void onClick(AjaxRequestTarget target) {
            coverageCheckModal.setContent(
                new NoContractCoveragePanel(coverageCheckModal.getContentId(), coverageCheckModal));
            coverageCheckModal.show(target);
          }
        };
    form.add(ppcmLink);

    Map<LengthProperty, Integer> fieldLengths = this.getLengthProperties();

    final ModalWindow printOrEmailModal = new ModalWindow("printOrEmailModal");
    printOrEmailModal.setHeightUnit("px");
    printOrEmailModal.setInitialHeight(Util.getInt(getString("printOrEmailPopup.height"), 220));
    printOrEmailModal.setWidthUnit("px");
    printOrEmailModal.setInitialWidth(Util.getInt(getString("printOrEmailPopup.width"), 440));
    printOrEmailModal.setResizable(false);
    printOrEmailModal.setWindowClosedCallback(
        new WindowClosedCallback() {

          private static final long serialVersionUID = 1L;

          @Override
          public void onClose(AjaxRequestTarget target) {
            target.add(form);
          }
        });

    /**
     * Launches dialog to perform either a print or email of the current recommendation worksheet
     */
    final AjaxButton printOrEmail =
        new AjaxButton("printOrEmailBtn") {

          private static final long serialVersionUID = 1L;

          @Override
          public void onSubmit(AjaxRequestTarget target, Form<?> form) {
            logger.debug("in print or email handler");
            saveRecSheet();
            printOrEmailModal.show(target);
          }

          @Override
          protected void onError(AjaxRequestTarget target, Form<?> form) {
            // TODO Implement me!
          }
        };
    form.add(printOrEmail);
    printOrEmail.setOutputMarkupPlaceholderTag(true);

    // print or email modal dialog
    add(printOrEmailModal);
    printOrEmailModal.setPageCreator(
        new ModalWindow.PageCreator() {

          private static final long serialVersionUID = 1L;

          public Page createPage() {
            return new PrintOrEmailDialog(model.getObject());
          }
        });

    printOrEmailModal.setCloseButtonCallback(
        new ModalWindow.CloseButtonCallback() {

          public boolean onCloseButtonClicked(AjaxRequestTarget target) {
            target.prependJavaScript("doLoad();");
            return true;
          }
        });

    /** Saves the rec sheet */
    final Button saveButton =
        new Button("saveBtn") {

          private static final long serialVersionUID = 1L;

          @Override
          public void onSubmit() {
            logger.debug("saving recsheet by button request");
            saveRecSheet();
          }
        };

    // save rec sheet button
    form.add(saveButton);
    saveButton.setOutputMarkupPlaceholderTag(true);

    // === Clear screen prompt and components ===
    final ModalWindow clearModal = new ModalWindow("clearModal");
    final AjaxButton clearButton =
        new AjaxButton("clearButton") {

          private static final long serialVersionUID = 1L;

          @Override
          public void onSubmit(AjaxRequestTarget target, Form<?> form) {

            String message =
                "Clear customer data?\n\nThis will apply to both the Dashboard and the Recommendation Sheet.";

            final YesNoPanel clearPanel =
                new YesNoPanel(clearModal.getContentId(), message, clearModal);
            // changing button text.
            clearPanel.setYesButtonText("Clear");
            clearPanel.setNoButtonText("Back");

            clearModal.setContent(clearPanel);

            clearModal.setWindowClosedCallback(
                new ModalWindow.WindowClosedCallback() {

                  private static final long serialVersionUID = 1L;

                  @Override
                  public void onClose(AjaxRequestTarget target) {
                    if (clearPanel.getDialogResult()) {
                      logger.debug("clearing customer from recsheet.");
                      DailyRhythmPortalSession session = getDailyRhythmPortalSession();
                      session.clearBestBuyCustomer();
                      session.clearSearchCustomer();
                      session.clearCarrierCustomer();
                      Recommendation rec = new Recommendation();
                      rec.setCreatedOn(new Date());
                      rec.setCreatedBy(session.getDrpUser().getUserId());
                      rec.setTransferFlag(false);
                      DigitalRecSheetPage drsPage = new DigitalRecSheetPage(rec, mswPage);
                      setResponsePage(drsPage);
                    }
                  }
                });

            clearModal.show(target);
          }

          @Override
          protected void onError(AjaxRequestTarget target, Form<?> form) {
            // TODO Implement me!
          }
        };

    clearButton.setDefaultFormProcessing(false);
    form.add(clearButton);
    add(clearModal);
    // === END of Clear Components ===

    /*
     * Search Rec Sheet button Navigates back to rec sheet search page
     */

    // close button exit point with popup.
    final ModalWindow exitWithoutSavingModal = new ModalWindow("exitWithoutSavingModal");
    String message = "Are you sure you want to exit without saving your changes?";

    final YesNoPanel exitPanel =
        new YesNoPanel(exitWithoutSavingModal.getContentId(), message, exitWithoutSavingModal);
    exitWithoutSavingModal.setContent(exitPanel);

    exitWithoutSavingModal.setWindowClosedCallback(
        new ModalWindow.WindowClosedCallback() {

          private static final long serialVersionUID = 1L;

          @Override
          public void onClose(AjaxRequestTarget target) {
            if (exitPanel.getDialogResult()) {
              setResponsePage(mswPage);
            }
          }
        });
    add(exitWithoutSavingModal);

    /*
     * ===== Search Rec Sheet Button ===== Search Rec Sheet button Navigates
     * back to rec sheet search page
     */
    final AjaxButton searchButton =
        new AjaxButton("searchBtn") {

          private static final long serialVersionUID = 1L;

          @Override
          public void onSubmit(AjaxRequestTarget target, Form<?> form) {

            logger.debug("closing recSheet by return to search button request.");
            PageParameters parameters = mswPage.getPageParameters();
            setResponsePage(new MobileSalesWorkspacePage(parameters));
          }

          @Override
          protected void onError(AjaxRequestTarget target, Form<?> form) {
            // TODO Implement me!
          }
        };

    // this is a pure navigation button so we do not want form validation to
    // occur
    searchButton.setDefaultFormProcessing(false);
    closeForm.add(searchButton);

    /*
     * ===== Close Rec Sheet Button ===== Close Rec Sheet button Navigates
     * back to rec sheet search page
     */
    final AjaxButton closeButton =
        new AjaxButton("closeBtn") {

          private static final long serialVersionUID = 1L;

          @Override
          public void onSubmit(AjaxRequestTarget target, Form<?> form) {
            logger.debug("closing recSheet by close button request.");
            if (drpSession.getCustomer() == null) {
              setResponsePage(CustomerDashboardSearchPage.class);
            } else {
              setResponsePage(CustomerDashboardPage.class);
            }
          }

          @Override
          protected void onError(AjaxRequestTarget target, Form<?> form) {
            // TODO Implement me!
          }
        };

    closeButton.setDefaultFormProcessing(false);
    closeForm.add(closeButton);
    form.add(closeForm);

    closeButton.setOutputMarkupPlaceholderTag(true);

    // if recommendation comes in blank, the model creates a new one...
    // Therefore we shouldn't mess with it until we retrieve it from the
    // model.
    Recommendation r = model.getRecommendation();
    String phoneNum = user.getLocationPhoneNum() == null ? "" : user.getLocationPhoneNum();
    if (r.getId() == 0) { // new rec sheet
      r.setSpecialistContactInfo(user.getFirstName() + " " + phoneNum);
      r.setEmpCrtFrstNm(user.getFirstName());
      r.setEmpCrtLastNm(user.getLastName());
    } else {
      r.setEmpAltFrstNm(user.getFirstName());
      r.setEmpAltLastNm(user.getLastName());
    }
    Essentials e = r.getEssentials();

    // first name
    TextField fldFirstname =
        new RequiredTextField("firstName", new PropertyModel<String>(r, "firstName"));
    fldFirstname.add(
        new StringValidator.LengthBetweenValidator(
            fieldLengths.get(LengthProperty.FLD_FIRSTNAME_MINLENGTH),
            fieldLengths.get(LengthProperty.FLD_FIRSTNAME_LENGTH)));
    form.add(fldFirstname);

    // last name
    RequiredTextField fldLastname =
        new RequiredTextField("lastName", new PropertyModel<String>(r, "lastName"));
    fldLastname.add(
        new StringValidator.LengthBetweenValidator(
            fieldLengths.get(LengthProperty.FLD_LASTNAME_MINLENGTH),
            fieldLengths.get(LengthProperty.FLD_LASTNAME_LENGTH)));
    form.add(fldLastname);

    // mobile number
    final TextField mobile =
        new RequiredTextField("mobileNum", new PropertyModel<PhoneNumber>(this, "phoneNumber")) {

          private static final long serialVersionUID = 1L;

          @Override
          public <C> IConverter<C> getConverter(Class<C> type) {
            return new PhoneNumberConverter();
          }
        };
    mobile.add(
        new AjaxFormComponentUpdatingBehavior("onBlur") {

          private static final long serialVersionUID = 1L;

          @Override
          protected void onUpdate(AjaxRequestTarget target) {
            target.add(mobile);
          }
        });
    mobile.setMarkupId("mobileNum");
    form.add(mobile);

    form.add(
        new TextField("contacttime", new PropertyModel<String>(r, "bestTimeToContact"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_CONTACTTIME_LENGTH))));

    TextField tradeInValue =
        new TextField("tradeInValue", new PropertyModel<String>(r, "tradeInValue")) {

          private static final long serialVersionUID = 1L;

          @Override
          public <C> IConverter<C> getConverter(Class<C> type) {
            return new MoneyConverter();
          }
        };

    tradeInValue.add(new MinimumValidator<BigDecimal>(new BigDecimal(0)));
    form.add(tradeInValue);

    form.add(new CheckBox("upgradetext", new PropertyModel<Boolean>(r, "upgradeReminderText")));
    form.add(new CheckBox("upgradecall", new PropertyModel<Boolean>(r, "upgradeReminderCall")));

    // upgrade date
    DateTextField udate =
        new DateTextField(
            "upgradedate", new PropertyModel<Date>(r, "upgradeEligibilityDate"), "EEEE MM/dd/yy");
    DatePicker dp = new DatePicker();
    udate.add(dp);
    form.add(udate);

    // customer - plan features device. On left side of form, not to be
    // confused with recommended plan/features/device.
    form.add(
        new TextArea("planFeaturesDevice", new PropertyModel<String>(r, "subscriptionInfo"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_PLANFEATURESDEVICE_LENGTH))));
    form.add(
        new TextArea("internetuse", new PropertyModel<String>(r, "netUseInfo"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_INTERNETUSE_LENGTH))));

    form.add(
        new TextArea("rec_connectivity", new PropertyModel<String>(r, "recommendedSubscription"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_REC_CONNECTIVITY_LENGTH))));
    form.add(
        new TextArea("rec_phonedevice", new PropertyModel<String>(r, "recommendedDevice"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_REC_PHONEDEVICE_LENGTH))));
    form.add(
        new TextField("e_bluetooth", new PropertyModel<String>(e, "handsfree"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_ESSENTIAL_LENGTH))));
    form.add(
        new TextField("e_memory", new PropertyModel<String>(e, "memory"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_ESSENTIAL_LENGTH))));
    form.add(
        new TextField("e_accessories", new PropertyModel<String>(e, "accessories"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_ESSENTIAL_LENGTH))));
    form.add(
        new TextField("e_shields", new PropertyModel<String>(e, "shields"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_ESSENTIAL_LENGTH))));
    form.add(
        new TextField("e_chargers", new PropertyModel<String>(e, "chargers"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_ESSENTIAL_LENGTH))));
    form.add(
        new TextField("e_gsbtp", new PropertyModel<String>(e, "gsbtp"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_ESSENTIAL_LENGTH))));
    form.add(
        new TextField("e_buyback", new PropertyModel<String>(e, "buyback"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_ESSENTIAL_LENGTH))));
    form.add(
        new TextField("e_financing", new PropertyModel<String>(e, "financing"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_ESSENTIAL_LENGTH))));

    form.add(
        new TextArea("notes", new PropertyModel<String>(r, "notes"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_NOTES_LENGTH))));
    form.add(
        new TextArea("contactinfo", new PropertyModel<String>(r, "specialistContactInfo"))
            .add(
                new StringValidator.MaximumLengthValidator(
                    fieldLengths.get(LengthProperty.FLD_CONTACTINFO_LENGTH))));

    form.add(
        new CheckBox(
            "md_internet",
            new CheckboxModel(
                r, "deviceCapabilities", Recommendation.DeviceCapabilities.INTERNET.name())));
    form.add(
        new CheckBox(
            "md_email",
            new CheckboxModel(
                r, "deviceCapabilities", Recommendation.DeviceCapabilities.EMAIL.name())));
    form.add(
        new CheckBox(
            "md_music",
            new CheckboxModel(
                r, "deviceCapabilities", Recommendation.DeviceCapabilities.MUSIC.name())));
    form.add(
        new CheckBox(
            "md_video",
            new CheckboxModel(
                r, "deviceCapabilities", Recommendation.DeviceCapabilities.VIDEO.name())));
    form.add(
        new CheckBox(
            "md_photo",
            new CheckboxModel(
                r, "deviceCapabilities", Recommendation.DeviceCapabilities.PHOTO.name())));
    form.add(
        new CheckBox(
            "md_tv",
            new CheckboxModel(
                r, "deviceCapabilities", Recommendation.DeviceCapabilities.TV.name())));
    form.add(
        new CheckBox(
            "md_games",
            new CheckboxModel(
                r, "deviceCapabilities", Recommendation.DeviceCapabilities.GAMING.name())));
    form.add(
        new CheckBox(
            "md_texting",
            new CheckboxModel(
                r, "deviceCapabilities", Recommendation.DeviceCapabilities.TEXTING.name())));
    form.add(
        new CheckBox(
            "md_unlocked",
            new CheckboxModel(
                r, "deviceCapabilities", Recommendation.DeviceCapabilities.UNLOCKED.name())));
    form.add(
        new CheckBox(
            "md_nav",
            new CheckboxModel(
                r, "deviceCapabilities", Recommendation.DeviceCapabilities.NAVIGATION.name())));

    form.add(
        new CheckBox(
            "wow_data",
            new CheckboxModel(
                r, "wowRequirements", Recommendation.WowRequirements.DATATRANSFER.name())));
    form.add(
        new CheckBox(
            "wow_email",
            new CheckboxModel(
                r, "wowRequirements", Recommendation.WowRequirements.PERSONALEMAIL.name())));
    form.add(
        new CheckBox(
            "wow_bluetooth",
            new CheckboxModel(
                r, "wowRequirements", Recommendation.WowRequirements.BLUETOOTHPAIRING.name())));
    form.add(
        new CheckBox(
            "wow_apps",
            new CheckboxModel(
                r, "wowRequirements", Recommendation.WowRequirements.APPLICATIONS.name())));
    form.add(
        new CheckBox(
            "wow_sw",
            new CheckboxModel(
                r, "wowRequirements", Recommendation.WowRequirements.SOFTWARE.name())));
    form.add(
        new CheckBox(
            "wow_social",
            new CheckboxModel(
                r, "wowRequirements", Recommendation.WowRequirements.SOCIALNETWORKING.name())));
    form.add(
        new CheckBox(
            "wow_power",
            new CheckboxModel(
                r, "wowRequirements", Recommendation.WowRequirements.POWERMANAGEMENT.name())));
    form.add(
        new CheckBox(
            "wow_voicemail",
            new CheckboxModel(
                r, "wowRequirements", Recommendation.WowRequirements.VOICEMAIL.name())));
    form.add(
        new CheckBox(
            "wow_other",
            new CheckboxModel(r, "wowRequirements", Recommendation.WowRequirements.OTHER.name())));

    HiddenField formChanged =
        new HiddenField<Boolean>("formChanged", new PropertyModel<Boolean>(this, "formChanged"));
    closeForm.add(formChanged);

    add(form);
    form.add(closeForm);

    SessionTimeoutPanel sessionTimeoutPanel = new SessionTimeoutPanel("sessionTimeoutPanel");
    add(sessionTimeoutPanel);
    sessionTimeoutPanel.setOutputMarkupPlaceholderTag(true);
  }