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); }
/** * @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); } }
/** * 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); }