Пример #1
0
  public void update(Integer entityId, NewInvoiceDTO addition) {
    // add the lines to the invoice first
    createLines(addition);
    // update the inoice record considering the new lines
    invoice.setTotal(calculateTotal()); // new total
    // adjust the balance
    addition.calculateTotal();
    BigDecimal balance = invoice.getBalance();
    balance = balance.add(addition.getTotal());
    invoice.setBalance(balance);

    if (invoice.getBalance().compareTo(BigDecimal.ZERO) == 0) {
      invoice.setToProcess(Integer.valueOf(0));
    }

    if (addition.getMetaFields() != null && !addition.getMetaFields().isEmpty()) {
      invoice.updateMetaFieldsWithValidation(entityId, addition);
    }
  }
Пример #2
0
  public void createLines(NewInvoiceDTO newInvoice) {
    Collection invoiceLines = invoice.getInvoiceLines();

    // Now create all the invoice lines, from the lines in the DTO
    // put there by the invoice composition pluggable tasks
    InvoiceLineDAS invoiceLineDas = new InvoiceLineDAS();

    // get the result DTO lines
    Iterator dueInvoiceLines = newInvoice.getResultLines().iterator();
    // go over the DTO lines, creating one invoice line for each

    // #2196 - GET Invoice Rounding Preference for entity entityId
    PreferenceBL pref = new PreferenceBL();
    Integer entityId = newInvoice.getEntityId();
    if (null == entityId) {
      entityId = newInvoice.getBaseUser().getEntity().getId();
    }

    int decimals = Constants.BIGDECIMAL_SCALE;
    try {
      pref.set(entityId, Constants.PREFERENCE_INVOICE_DECIMALS);
      decimals = pref.getInt();
    } catch (EmptyResultDataAccessException e) {
      // ignore
    }
    // #2196

    while (dueInvoiceLines.hasNext()) {
      InvoiceLineDTO lineToAdd = (InvoiceLineDTO) dueInvoiceLines.next();
      // define if the line is a percentage or not
      lineToAdd.setIsPercentage(0);
      if (lineToAdd.getItem() != null) {
        try {
          ItemBL item = new ItemBL(lineToAdd.getItem());
          if (item.getEntity().getPercentage() != null) {
            lineToAdd.setIsPercentage(1);
          }
        } catch (SessionInternalError e) {
          LOG.error("Could not find item to create invoice line " + lineToAdd.getItem().getId());
        }
      }

      // #2196 - Use Invoice Rounding Preference to round Invoice Lines
      if (null != lineToAdd.getAmount()) {
        lineToAdd.setAmount(lineToAdd.getAmount().setScale(decimals, Constants.BIGDECIMAL_ROUND));
      }
      // #2196

      // create the database row
      InvoiceLineDTO newLine =
          invoiceLineDas.create(
              lineToAdd.getDescription(),
              lineToAdd.getAmount(),
              lineToAdd.getQuantity(),
              lineToAdd.getPrice(),
              lineToAdd.getTypeId(),
              lineToAdd.getItem(),
              lineToAdd.getSourceUserId(),
              lineToAdd.getIsPercentage());

      // update the invoice-lines relationship
      newLine.setInvoice(invoice);
      invoiceLines.add(newLine);
    }
    getHome().save(invoice);
    EventManager.process(new NewInvoiceEvent(invoice));
  }
Пример #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);
    }
  }