public Integer createUpdate(Integer executorId, BillingProcessConfigurationDTO dto) {
    configuration = configurationDas.findByEntity(dto.getEntity());
    if (configuration != null) {

      if (!configuration.getGenerateReport().equals(dto.getGenerateReport())) {
        eLogger.audit(
            executorId,
            null,
            Constants.TABLE_BILLING_PROCESS_CONFIGURATION,
            configuration.getId(),
            EventLogger.MODULE_BILLING_PROCESS,
            EventLogger.ROW_UPDATED,
            new Integer(configuration.getGenerateReport()),
            null,
            null);
        configuration.setGenerateReport(dto.getGenerateReport());
        configuration.setReviewStatus(
            dto.getGenerateReport() == 1
                ? Constants.REVIEW_STATUS_GENERATED
                : Constants.REVIEW_STATUS_APPROVED);
      } else {
        eLogger.audit(
            executorId,
            null,
            Constants.TABLE_BILLING_PROCESS_CONFIGURATION,
            configuration.getId(),
            EventLogger.MODULE_BILLING_PROCESS,
            EventLogger.ROW_UPDATED,
            null,
            null,
            null);
      }

      configuration.setNextRunDate(dto.getNextRunDate());
    } else {
      configuration =
          configurationDas.create(dto.getEntity(), dto.getNextRunDate(), dto.getGenerateReport());
    }

    configuration.setDaysForReport(dto.getDaysForReport());
    configuration.setDaysForRetry(dto.getDaysForRetry());
    configuration.setRetries(dto.getRetries());
    configuration.setPeriodUnit(dto.getPeriodUnit());
    configuration.setPeriodValue(dto.getPeriodValue());
    configuration.setDueDateUnitId(dto.getDueDateUnitId());
    configuration.setDueDateValue(dto.getDueDateValue());
    configuration.setDfFm(dto.getDfFm());
    configuration.setOnlyRecurring(dto.getOnlyRecurring());
    configuration.setInvoiceDateProcess(dto.getInvoiceDateProcess());
    configuration.setAutoPayment(dto.getAutoPayment());
    configuration.setAutoPaymentApplication(dto.getAutoPaymentApplication());
    configuration.setMaximumPeriods(dto.getMaximumPeriods());

    return configuration.getId();
  }
  public void setReviewApproval(Integer executorId, boolean flag) {

    eLogger.audit(
        executorId,
        null,
        Constants.TABLE_BILLING_PROCESS_CONFIGURATION,
        configuration.getId(),
        EventLogger.MODULE_BILLING_PROCESS,
        EventLogger.ROW_UPDATED,
        configuration.getReviewStatus(),
        null,
        null);
    configuration.setReviewStatus(
        flag ? Constants.REVIEW_STATUS_APPROVED : Constants.REVIEW_STATUS_DISAPPROVED);
  }
Example #3
0
  /**
   * @param userId
   * @param newInvoice
   * @param process It can be null.
   */
  public void create(
      Integer userId, NewInvoiceDTO newInvoice, BillingProcessDTO process, Integer executorUserId) {
    // find out the entity id
    PreferenceBL pref = new PreferenceBL();
    UserBL user = null;
    Integer entityId;
    if (process != null) {
      entityId = process.getEntity().getId();
    } else {
      // this is a manual invoice, there's no billing process
      user = new UserBL(userId);
      entityId = user.getEntityId(userId);
    }

    // verify if this entity is using the 'continuous invoice date'
    // preference
    try {
      pref.set(entityId, Constants.PREFERENCE_CONTINUOUS_DATE);

      if (StringUtils.isNotBlank(pref.getString())) {
        Date lastDate = com.sapienter.jbilling.common.Util.parseDate(pref.getString());
        LOG.debug("Last date invoiced: " + lastDate);

        if (lastDate.after(newInvoice.getBillingDate())) {
          LOG.debug(
              "Due date is before the last recorded date. Moving due date forward for continuous invoice dates.");
          newInvoice.setBillingDate(lastDate);

        } else {
          // update the lastest date only if this is not a review
          if (newInvoice.getIsReview() == null || newInvoice.getIsReview() == 0) {
            pref.createUpdateForEntity(
                entityId,
                Constants.PREFERENCE_CONTINUOUS_DATE,
                com.sapienter.jbilling.common.Util.parseDate(newInvoice.getBillingDate()));
          }
        }
      }
    } catch (EmptyResultDataAccessException e) {
      // not interested, ignore
    }

    // in any case, ensure that the due date is => that invoice date
    if (newInvoice.getDueDate().before(newInvoice.getBillingDate())) {
      LOG.debug("Due date before billing date, moving date up to billing date.");
      newInvoice.setDueDate(newInvoice.getBillingDate());
    }

    // ensure that there are only so many decimals in the invoice
    int decimals = Constants.BIGDECIMAL_SCALE;
    try {
      pref.set(entityId, Constants.PREFERENCE_INVOICE_DECIMALS);
      decimals = pref.getInt();
    } catch (EmptyResultDataAccessException e) {
      // not interested, ignore
    }

    LOG.debug("Rounding " + newInvoice.getTotal() + " to " + decimals + " decimals");
    if (newInvoice.getTotal() != null) {
      newInvoice.setTotal(newInvoice.getTotal().setScale(decimals, Constants.BIGDECIMAL_ROUND));
    }
    if (newInvoice.getBalance() != null) {
      newInvoice.setBalance(newInvoice.getBalance().setScale(decimals, Constants.BIGDECIMAL_ROUND));
    }

    // some API calls only accept ID's and do not pass meta-fields
    // update and validate meta-fields if they've been populated
    if (newInvoice.getMetaFields() != null && !newInvoice.getMetaFields().isEmpty()) {
      newInvoice.updateMetaFieldsWithValidation(entityId, newInvoice);
    }

    // create the invoice row
    invoice = invoiceDas.create(userId, newInvoice, process);

    // add delegated/included invoice links
    if (newInvoice.getIsReview() == 0) {
      for (InvoiceDTO dto : newInvoice.getInvoices()) {
        dto.setInvoice(invoice);
      }
    }

    // add the customer notes if it applies
    try {
      pref.set(entityId, Constants.PREFERENCE_SHOW_NOTE_IN_INVOICE);
    } catch (EmptyResultDataAccessException e) {
      // use the default then
    }

    if (pref.getInt() == 1) {
      if (user == null) {
        user = new UserBL(userId);
      }
      if (user.getEntity().getCustomer() != null
          && user.getEntity().getCustomer().getNotes() != null) {
        // append the notes if there's some text already there
        newInvoice.setCustomerNotes(
            (newInvoice.getCustomerNotes() == null)
                ? user.getEntity().getCustomer().getNotes()
                : newInvoice.getCustomerNotes() + " " + user.getEntity().getCustomer().getNotes());
      }
    }
    // notes might come from the customer, the orders, or both
    if (newInvoice.getCustomerNotes() != null && newInvoice.getCustomerNotes().length() > 0) {
      invoice.setCustomerNotes(newInvoice.getCustomerNotes());
    }

    // calculate/compose the number
    String numberStr = null;
    if (newInvoice.getIsReview() != null && newInvoice.getIsReview() == 1) {
      // invoices for review will be seen by the entity employees
      // so the entity locale will be used
      EntityBL entity = new EntityBL(entityId);
      ResourceBundle bundle = ResourceBundle.getBundle("entityNotifications", entity.getLocale());
      numberStr = bundle.getString("invoice.review.number");
    } else if (newInvoice.getPublicNumber() == null || newInvoice.getPublicNumber().length() == 0) {
      String prefix;
      try {
        pref.set(entityId, Constants.PREFERENCE_INVOICE_PREFIX);
        prefix = pref.getString();
        if (prefix == null) {
          prefix = "";
        }
      } catch (EmptyResultDataAccessException e) {
        prefix = "";
      }
      int number;
      try {
        pref.set(entityId, Constants.PREFERENCE_INVOICE_NUMBER);
        number = pref.getInt();
      } catch (EmptyResultDataAccessException e1) {
        number = 1;
      }

      numberStr = prefix + number;
      // update for the next time
      number++;
      pref.createUpdateForEntity(entityId, Constants.PREFERENCE_INVOICE_NUMBER, number);
    } else { // for upload of legacy invoices
      numberStr = newInvoice.getPublicNumber();
    }

    invoice.setPublicNumber(numberStr);

    // set the invoice's contact info with the current user's primary
    ContactBL contact = new ContactBL();
    contact.set(userId);
    contact.createForInvoice(contact.getDTO(), invoice.getId());

    // add a log row for convenience
    if (null != executorUserId) {
      eLogger.audit(
          executorUserId,
          userId,
          Constants.TABLE_INVOICE,
          invoice.getId(),
          EventLogger.MODULE_INVOICE_MAINTENANCE,
          EventLogger.ROW_CREATED,
          null,
          null,
          null);
    } else {
      eLogger.auditBySystem(
          entityId,
          userId,
          Constants.TABLE_INVOICE,
          invoice.getId(),
          EventLogger.MODULE_INVOICE_MAINTENANCE,
          EventLogger.ROW_CREATED,
          null,
          null,
          null);
    }
  }
Example #4
0
  /**
   * This will remove all the records (sql delete, not just flag them). It will also update the
   * related orders if applicable
   */
  public void delete(Integer executorId) throws SessionInternalError {
    if (invoice == null) {
      throw new SessionInternalError("An invoice has to be set before delete");
    }

    // prevent a delegated Invoice from being deleted
    if (invoice.getDelegatedInvoiceId() != null && invoice.getDelegatedInvoiceId().intValue() > 0) {
      SessionInternalError sie =
          new SessionInternalError("A carried forward Invoice cannot be deleted");
      sie.setErrorMessages(
          new String[] {"InvoiceDTO,invoice,invoice.error.fkconstraint," + invoice.getId()});
      throw sie;
    }
    // start by updating purchase_order.next_billable_day if applicatble
    // for each of the orders included in this invoice
    for (OrderProcessDTO orderProcess : (Collection<OrderProcessDTO>) invoice.getOrderProcesses()) {
      OrderDTO order = orderProcess.getPurchaseOrder();
      if (order.getNextBillableDay() == null) {
        // the next billable day doesn't need updating
        if (order.getStatusId().equals(Constants.ORDER_STATUS_FINISHED)) {
          OrderBL orderBL = new OrderBL(order);
          orderBL.setStatus(null, Constants.ORDER_STATUS_ACTIVE);
        }
        continue;
      }
      // only if this invoice is the responsible for the order's
      // next billable day
      if (order.getNextBillableDay().equals(orderProcess.getPeriodEnd())) {
        order.setNextBillableDay(orderProcess.getPeriodStart());
        if (order.getStatusId().equals(Constants.ORDER_STATUS_FINISHED)) {
          OrderBL orderBL = new OrderBL(order);
          orderBL.setStatus(null, Constants.ORDER_STATUS_ACTIVE);
        }
      }
    }

    // go over the order process records again just to delete them
    // we are done with this order, delete the process row
    for (OrderProcessDTO orderProcess : (Collection<OrderProcessDTO>) invoice.getOrderProcesses()) {
      OrderDTO order = orderProcess.getPurchaseOrder();
      OrderProcessDAS das = new OrderProcessDAS();
      order.getOrderProcesses().remove(orderProcess);
      das.delete(orderProcess);
    }
    invoice.getOrderProcesses().clear();

    // get rid of the contact associated with this invoice
    try {
      ContactBL contact = new ContactBL();
      if (contact.setInvoice(invoice.getId())) {
        contact.delete();
      }
    } catch (Exception e1) {
      LOG.error("Exception deleting the contact of an invoice", e1);
    }

    // remove the payment link/s
    PaymentBL payment = new PaymentBL();
    Iterator<PaymentInvoiceMapDTO> it = invoice.getPaymentMap().iterator();
    while (it.hasNext()) {
      PaymentInvoiceMapDTO map = it.next();
      payment.removeInvoiceLink(map.getId());
      invoice.getPaymentMap().remove(map);
      // needed because the collection has changed
      it = invoice.getPaymentMap().iterator();
    }

    // log that this was deleted, otherwise there will be no trace
    if (executorId != null) {
      eLogger.audit(
          executorId,
          invoice.getBaseUser().getId(),
          Constants.TABLE_INVOICE,
          invoice.getId(),
          EventLogger.MODULE_INVOICE_MAINTENANCE,
          EventLogger.ROW_DELETED,
          null,
          null,
          null);
    }

    // before delete the invoice most delete the reference in table
    // PAYMENT_INVOICE
    new PaymentInvoiceMapDAS().deleteAllWithInvoice(invoice);

    Set<InvoiceDTO> invoices = invoice.getInvoices();
    if (invoices.size() > 0) {
      for (InvoiceDTO delegate : invoices) {
        // set status to unpaid as against carried
        delegate.setInvoiceStatus(new InvoiceStatusDAS().find(Constants.INVOICE_STATUS_UNPAID));
        // remove delegated invoice link
        delegate.setInvoice(null);
        getHome().save(delegate);
      }
    }

    // now delete the invoice itself
    getHome().delete(invoice);
    getHome().flush();
  }
  /**
   * Sets the user status to the given "aged" status. If the user status is already set to the aged
   * status no changes will be made. This method also performs an HTTP callback and sends a
   * notification message when a status change is made.
   *
   * <p>If the user becomes suspended and can no longer log-in to the system, all of their active
   * orders will be automatically suspended.
   *
   * <p>If the user WAS suspended and becomes active (and can now log-in to the system), any
   * automatically suspended orders will be re-activated.
   *
   * @param user user
   * @param status status to set
   * @param today today's date
   * @param executorId executor id
   */
  public void setUserStatus(UserDTO user, UserStatusDTO status, Date today, Integer executorId) {
    // only set status if the new "aged" status is different from the users current status
    if (status.getId() == user.getStatus().getId()) {
      return;
    }

    LOG.debug("Setting user " + user.getId() + " status to '" + getStatusDescription(status) + "'");

    if (executorId != null) {
      // this came from the gui
      eLogger.audit(
          executorId,
          user.getId(),
          Constants.TABLE_BASE_USER,
          user.getId(),
          EventLogger.MODULE_USER_MAINTENANCE,
          EventLogger.STATUS_CHANGE,
          user.getStatus().getId(),
          null,
          null);
    } else {
      // this is from a process, no executor involved
      eLogger.auditBySystem(
          user.getCompany().getId(),
          user.getId(),
          Constants.TABLE_BASE_USER,
          user.getId(),
          EventLogger.MODULE_USER_MAINTENANCE,
          EventLogger.STATUS_CHANGE,
          user.getStatus().getId(),
          null,
          null);
    }

    // make the change
    boolean couldLogin = user.getStatus().getCanLogin() == 1;
    UserStatusDTO oldStatus = user.getStatus();

    user.setUserStatus(status);
    user.setLastStatusChange(today);

    // status changed to deleted, remove user
    if (status.getId() == UserDTOEx.STATUS_DELETED) {
      LOG.debug("Deleting user " + user.getId());
      new UserBL(user.getId()).delete(executorId);
      return;
    }

    // status changed from active to suspended
    // suspend customer orders
    if (couldLogin && status.getCanLogin() == 0) {
      LOG.debug("User " + user.getId() + " cannot log-in to the system. Suspending active orders.");

      OrderBL orderBL = new OrderBL();
      ScrollableResults orders =
          new OrderDAS().findByUser_Status(user.getId(), Constants.ORDER_STATUS_ACTIVE);

      while (orders.next()) {
        OrderDTO order = (OrderDTO) orders.get()[0];
        orderBL.set(order);
        orderBL.setStatus(executorId, Constants.ORDER_STATUS_SUSPENDED_AGEING);
      }

      orders.close();
    }

    // status changed from suspended to active
    // re-active suspended customer orders
    if (!couldLogin && status.getCanLogin() == 1) {
      LOG.debug(
          "User "
              + user.getId()
              + " can now log-in to the system. Activating previously suspended orders.");

      OrderBL orderBL = new OrderBL();
      ScrollableResults orders =
          new OrderDAS().findByUser_Status(user.getId(), Constants.ORDER_STATUS_SUSPENDED_AGEING);

      while (orders.next()) {
        OrderDTO order = (OrderDTO) orders.get()[0];
        orderBL.set(order);
        orderBL.setStatus(executorId, Constants.ORDER_STATUS_ACTIVE);
      }

      orders.close();
    }

    // perform callbacks and notifications
    performAgeingCallback(user, oldStatus, status);
    sendAgeingNotification(user, oldStatus, status);

    // emit NewUserStatusEvent
    NewUserStatusEvent event =
        new NewUserStatusEvent(
            user.getCompany().getId(), user.getId(), oldStatus.getId(), status.getId());
    EventManager.process(event);
  }