예제 #1
0
  /** @return Returns the invoiceItemSubTotalAmount. */
  public BigDecimal getInvoiceItemSubTotalAmount() {
    // this needs to be calculated when read
    BigDecimal returnValue;
    if (((this.invoiceItemQuantity != null)
            && ((BigDecimal.ZERO.compareTo(this.invoiceItemQuantity)) != 0))
        && ((this.invoiceItemUnitPrice != null)
            && ((BigDecimal.ZERO.compareTo(this.invoiceItemUnitPrice)) != 0))) {
      // unit price and quantity are valid... calculate subtotal
      returnValue = this.invoiceItemQuantity.multiply(this.invoiceItemUnitPrice);
    } else if (((this.invoiceItemQuantity == null) || ("".equals(this.invoiceItemQuantity)))
        && ((this.invoiceItemUnitPrice != null)
            && ((BigDecimal.ZERO.compareTo(this.invoiceItemUnitPrice)) != 0))) {
      // quantity is empty but unit cost exists... use it
      returnValue = this.invoiceItemUnitPrice;
    } else {
      returnValue = null;
    }

    if (returnValue != null) {
      invoiceItemSubTotalAmount = returnValue.setScale(4, BigDecimal.ROUND_HALF_UP);
    } else {
      invoiceItemSubTotalAmount = null;
    }

    return invoiceItemSubTotalAmount;
  }
예제 #2
0
 /**
  * 数值求余处理
  *
  * @param num1 被除数
  * @param num2 除数
  * @return 余数
  */
 public static BigDecimal remainder(BigDecimal num1, BigDecimal num2) {
   if (null == num2 || BigDecimal.ZERO.compareTo(num2) == 0) {
     return null;
   }
   if (null == num1 || BigDecimal.ZERO.compareTo(num1) == 0) {
     return BigDecimal.ZERO;
   }
   return num1.remainder(num2);
 }
예제 #3
0
 private BigDecimal randomExpenseAmount(Account account, Date date, Double part) {
   BigDecimal balance = balanceWorker.getBalance(account.getId(), date);
   if (BigDecimal.ZERO.compareTo(balance) >= 0) return BigDecimal.ZERO;
   else {
     return new BigDecimal((int) (Math.random() * balance.doubleValue() * part));
   }
 }
예제 #4
0
  private void transfer(final Date date, final Account account1, final Account account2) {
    persistence.runInTransaction(
        em -> {
          BigDecimal amount1 = randomExpenseAmount(account1, date, 0.5);
          if (BigDecimal.ZERO.compareTo(amount1) >= 0) return;

          BigDecimal amount2 = transferAmount(account1, account2, amount1);

          Operation operation = metadata.create(Operation.class);
          operation.setOpType(OperationType.TRANSFER);
          operation.setOpDate(date);
          operation.setAcc1(account1);
          operation.setAmount1(amount1);
          operation.setAcc2(account2);
          operation.setAmount2(amount2);
          em.persist(operation);

          log.info(
              "Transfer: "
                  + date
                  + ", "
                  + account1.getName()
                  + ", "
                  + amount1
                  + ", "
                  + account2.getName()
                  + ", "
                  + amount2);
        });
  }
예제 #5
0
 private static BigDecimal defaultToNullIfZero(final BigDecimal value) {
   BigDecimal result = value;
   if (value != null && BigDecimal.ZERO.compareTo(value) == 0) {
     result = null;
   }
   return result;
 }
예제 #6
0
  public boolean process(PaymentDTOEx payment) throws PluggableTaskException {
    LOG.debug("Payment processing for " + getProcessorName() + " gateway");

    if (payment.getPayoutId() != null) return true;

    SvcType transaction = SvcType.SALE;
    if (BigDecimal.ZERO.compareTo(payment.getAmount()) > 0 || (payment.getIsRefund() != 0)) {
      LOG.debug("Doing a refund using credit card transaction");
      transaction = SvcType.REFUND_CREDIT;
    }

    boolean result;
    try {
      result = doProcess(payment, transaction, null).shouldCallOtherProcessors();
      LOG.debug(
          "Processing result is "
              + payment.getPaymentResult().getId()
              + ", return value of process is "
              + result);

    } catch (Exception e) {
      LOG.error("Exception", e);
      throw new PluggableTaskException(e);
    }
    return result;
  }
예제 #7
0
  public void deposit(BigDecimal amount) {

    if (BigDecimal.ZERO.compareTo(amount) == 0) {
      throw new IllegalArgumentException("Amount must be greater than zero/");
    }

    transactions.add(new Transaction(amount, Transaction.Type.DEPOSIT));
  }
예제 #8
0
  public Product(String name, BigDecimal price, String description) {
    Assert.hasText(name, "Name must not be null or empty!");
    Assert.isTrue(BigDecimal.ZERO.compareTo(price) < 0, "Price must be greater than zero!");

    this.name = name;
    this.price = price;
    this.description = description;
  }
예제 #9
0
  public static List<OrderLineDTO> diffOrderLines(
      List<OrderLineDTO> lines1, List<OrderLineDTO> lines2) {

    List<OrderLineDTO> diffLines = new ArrayList<OrderLineDTO>();

    Collections.sort(
        lines1,
        new Comparator<OrderLineDTO>() {
          public int compare(OrderLineDTO a, OrderLineDTO b) {
            return new Integer(a.getId()).compareTo(b.getId());
          }
        });

    for (OrderLineDTO line : lines2) {
      int index =
          Collections.binarySearch(
              lines1,
              line,
              new Comparator<OrderLineDTO>() {
                public int compare(OrderLineDTO a, OrderLineDTO b) {
                  return new Integer(a.getId()).compareTo(b.getId());
                }
              });

      if (index >= 0) {
        // existing line
        OrderLineDTO diffLine = new OrderLineDTO(lines1.get(index));

        // will fail if amounts or quantities are null...
        diffLine.setAmount(line.getAmount().subtract(diffLine.getAmount()));
        diffLine.setQuantity(line.getQuantity().subtract(diffLine.getQuantity()));

        if (BigDecimal.ZERO.compareTo(diffLine.getAmount()) != 0
            || BigDecimal.ZERO.compareTo(diffLine.getQuantity()) != 0) {
          diffLines.add(diffLine);
        }
      } else {
        // new line
        diffLines.add(new OrderLineDTO(line));
      }
    }

    LOG.debug("Diff lines are %s", diffLines);
    return diffLines;
  }
예제 #10
0
  /**
   * Creates a new {@link Product} from the given name and description.
   *
   * @param id a unique Id
   * @param name must not be {@literal null} or empty.
   * @param price must not be {@literal null} or less than or equal to zero.
   * @param description
   */
  @PersistenceConstructor
  public Product(Long id, String name, BigDecimal price, String description) {
    super(id);
    Assert.hasText(name, "Name must not be null or empty!");
    Assert.isTrue(BigDecimal.ZERO.compareTo(price) < 0, "Price must be greater than zero!");

    this.name = name;
    this.price = price;
    this.description = description;
  }
  public void process(Event event) throws PluggableTaskException {
    if (event instanceof SubscriptionActiveEvent) {
      SubscriptionActiveEvent activeEvent = (SubscriptionActiveEvent) event;

      LOG.debug("Processing order " + activeEvent.getOrder().getId() + " subscription activation");
      doActivate(activeEvent.getOrder(), activeEvent.getOrder().getLines());

    } else if (event instanceof SubscriptionInactiveEvent) {
      SubscriptionInactiveEvent inactiveEvent = (SubscriptionInactiveEvent) event;

      LOG.debug(
          "Processing order " + inactiveEvent.getOrder().getId() + " subscription deactivation");
      doDeactivate(inactiveEvent.getOrder(), inactiveEvent.getOrder().getLines());

    } else if (event instanceof NewQuantityEvent) {
      NewQuantityEvent quantityEvent = (NewQuantityEvent) event;

      if (BigDecimal.ZERO.compareTo(quantityEvent.getOldQuantity()) != 0
          && BigDecimal.ZERO.compareTo(quantityEvent.getNewQuantity()) != 0) {
        LOG.debug("Order line quantities did not change, no provisioning necessary.");
        return;
      }

      OrderDTO order = new OrderBL(quantityEvent.getOrderId()).getEntity();
      if (!isOrderProvisionable(order)) {
        LOG.warn("Order is not active and cannot be provisioned.");
        return;
      }

      if (BigDecimal.ZERO.compareTo(quantityEvent.getOldQuantity()) == 0) {
        LOG.debug("Processing order " + order.getId() + " activation");
        doActivate(order, Arrays.asList(quantityEvent.getOrderLine()));
      }

      if (BigDecimal.ZERO.compareTo(quantityEvent.getNewQuantity()) == 0) {
        LOG.debug("Processing order " + order.getId() + " deactivation");
        doDeactivate(order, Arrays.asList(quantityEvent.getOrderLine()));
      }

    } else {
      throw new PluggableTaskException("Cannot process event " + event);
    }
  }
예제 #12
0
  public void withdraw(BigDecimal amount) {
    if (BigDecimal.ZERO.compareTo(amount) == 0) {
      throw new IllegalArgumentException("Amount must be greater than zero.");
    }

    if (sumTransactions().compareTo(amount) < 0) {
      throw new IllegalArgumentException("Customer doesn't have enough money to cover withdrawal");
    }
    // TBD watch the sign direction on these
    transactions.add(new Transaction(amount.negate(), Transaction.Type.WITHDRAWAL));
  }
예제 #13
0
  @Test
  public final void shouldConvertNullToZero() {
    // given
    BigDecimal notNullDecimal = BigDecimal.TEN;

    // when
    BigDecimal fromNullRes = BigDecimalUtils.convertNullToZero(null);
    BigDecimal fromNotNullRes = BigDecimalUtils.convertNullToZero(notNullDecimal);

    // then
    Assert.assertEquals(0, notNullDecimal.compareTo(fromNotNullRes));
    Assert.assertEquals(0, BigDecimal.ZERO.compareTo(fromNullRes));
  }
예제 #14
0
  public void testNegativeZero(int scale, IonDecimal actual) {
    assertEquals(-0f, actual.floatValue());
    assertEquals(-0d, actual.doubleValue());

    BigDecimal bd = actual.bigDecimalValue();
    Decimal dec = actual.decimalValue();

    assertEquals(0, BigDecimal.ZERO.compareTo(bd));

    checkDecimal(0, scale, bd);
    checkDecimal(0, scale, dec);
    assertEquals(0, Decimal.NEGATIVE_ZERO.compareTo(dec));
    assertTrue(dec.isNegativeZero());
  }
  private IcScriptUploadTradeRequestEntity packUp(
      CupsTrmnl cupsTrmnl, CupsKeyManage cupsKeyManage, PepsiColaRequestInfo request)
      throws TransferFailedException {
    if (request.getIcScript() == null) {
      throw new TransferFailedException(
          AppExCode.ILLEGAL_PARAMS, "isScript upload failed! IcScript objet is null");
    }
    PayCups originalPayCups = payCupsService.findPayCups(request.getOriginalPayNo());
    // 脚本上送打包
    IcScriptUploadTradeRequestEntity entity = new IcScriptUploadTradeRequestEntity();
    entity.setCardNo(originalPayCups.getCardNo()); // 2 卡号
    entity.setProcessCode(originalPayCups.getProcessCode()); // 3 未选卡种
    String amount = null;
    if (originalPayCups.getTransAmt() != null
        || BigDecimal.ZERO.compareTo(originalPayCups.getTransAmt()) != 0) {
      amount = com.newland.base.util.StringUtils.amtToBCD(originalPayCups.getTransAmt());
    }
    entity.setTransAmt(amount); // 4 交易金额
    entity.setTrmnlFlowNo(cupsTrmnl.getTrmnlFlowNo()); // 11 终端流水号
    entity.setPosEntryMode(originalPayCups.getPosEntryMode()); // 22 卡输入方式
    if (StringUtils.isBlank(originalPayCups.getIcData())) { // 磁条卡
      entity.setSelfDefined60(
          Const.SD60_1_MSGTYPE_CONTROL
              + cupsTrmnl.getTrmnlBatchNo()); // 60 自定义域 22(交易类型码)+000001(批次号)+000(网络管理信息码)
    } else { // IC卡
      entity.setCardSeqNum(originalPayCups.getCardSeqNum()); // IC卡必须上送该域
      byte[] icData = getIcData(originalPayCups.getIcData(), request.getIcScript());
      entity.setIcData(icData); // 55 IC卡数据
      String selfDefined60 =
          Const.SD60_1_MSGTYPE_CONTROL
              + cupsTrmnl.getTrmnlBatchNo()
              + Const.SD60_3_IC_CRIPT_UPLOAD
              + Const.SD60_4_TERMINAL_READING_ABILITY_CONTACT_ICCARD
              + Const.SD60_5_IC_SERVICE_CODE_NORMAL;
      entity.setSelfDefined60(selfDefined60);
    }
    entity.setTrmnlRefferNo(originalPayCups.getTrmnlReferNo()); // 37
    entity.setTrmnlNo(originalPayCups.getTrmnlNo()); // 41 终端号
    entity.setTrmnlMrchNo(originalPayCups.getTrmnlMrchNo()); // 42 终端商户号
    entity.setCurrency(originalPayCups.getCurrency()); // 49 货币代码
    entity.setOriginalMessage(
        originalPayCups.getTrmnlBatchNo()
            + originalPayCups.getTrmnlFlowNo()
            + originalPayCups.getTransDate()); // 61 原批次号+原流水号
    entity.setMacCode(new byte[8]); // 64 mac

    return entity;
  }
예제 #16
0
  // One Time Bill
  public BillingOrderCommand getOneTimeBill(
      BillingOrderData billingOrderData, DiscountMasterData discountMasterData) {

    LocalDate endDate = null;
    LocalDate invoiceTillDate = null;
    LocalDate nextbillDate = null;
    List<InvoiceTaxCommand> listOfTaxes = new ArrayList<InvoiceTaxCommand>();

    LocalDate startDate = new LocalDate(billingOrderData.getBillStartDate());
    BigDecimal price = billingOrderData.getPrice();

    if (billingOrderData.getStartDate() != null) {
      endDate = startDate.plusMonths(billingOrderData.getChargeDuration()).minusDays(1);
      invoiceTillDate = endDate;
      nextbillDate = invoiceTillDate.plusDays(1);

    } else {
      endDate = startDate;
      invoiceTillDate = startDate;
      nextbillDate = invoiceTillDate;
    }

    if (discountMasterData != null
        && BigDecimal.ZERO.compareTo(discountMasterData.getDiscountAmount()) <= 1) {

      listOfTaxes =
          this.calculateTax(billingOrderData, discountMasterData.getDiscountedChargeAmount());
    } else {

      listOfTaxes = this.calculateTax(billingOrderData, billingOrderData.getPrice());
    }

    return this.createBillingOrderCommand(
        billingOrderData,
        startDate,
        endDate,
        invoiceTillDate,
        nextbillDate,
        price,
        listOfTaxes,
        discountMasterData);
  }
예제 #17
0
  private void expense(final Date date, final Account account, final Context context) {
    persistence.runInTransaction(
        em -> {
          int categoryIdx =
              (int) Math.round(Math.random() * (context.expenseCategories.size() - 1));
          Category category = context.expenseCategories.get(categoryIdx);
          if (category == null) return;

          int categoryWeight = context.expenseCategories.size() - categoryIdx;
          BigDecimal amount = randomExpenseAmount(account, date, 0.1 + (categoryWeight * 0.05));
          if (BigDecimal.ZERO.compareTo(amount) >= 0) return;

          Operation operation = metadata.create(Operation.class);
          operation.setOpType(OperationType.EXPENSE);
          operation.setOpDate(date);
          operation.setAcc1(account);
          operation.setCategory(category);
          operation.setAmount1(amount);
          em.persist(operation);

          log.info("Expense: " + date + ", " + account.getName() + ", " + amount);
        });
  }
예제 #18
0
 /**
  * Returns true is the value is zero
  *
  * @return a boolean
  */
 public boolean isZero() {
   return (BigDecimal.ZERO.compareTo(value) == 0);
 }
예제 #19
0
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
      if (convertView == null) {
        convertView = inflater.inflate(R.layout.ext_cashila_pending_row, null);
      }

      final BillPay billPay = getItem(position);

      TextView tvName = ButterKnife.findById(convertView, R.id.tvName);
      TextView tvAmount = ButterKnife.findById(convertView, R.id.tvAmount);
      TextView tvOutstandingAmount = ButterKnife.findById(convertView, R.id.tvOutstandingAmount);
      TextView tvStatus = ButterKnife.findById(convertView, R.id.tvStatus);
      TextView tvFee = ButterKnife.findById(convertView, R.id.tvFee);
      TextView tvSectionHeader = ButterKnife.findById(convertView, R.id.tvSectionHeader);
      TextView tvReference = ButterKnife.findById(convertView, R.id.tvReference);
      TextView tvDate = ButterKnife.findById(convertView, R.id.tvDate);

      if (billPay.recipient != null) {
        tvName.setText(billPay.recipient.name);
      } else {
        tvName.setText("");
      }

      if (billPay.payment != null) {
        tvAmount.setText(
            Utils.formatFiatValueAsString(billPay.payment.amount) + " " + billPay.payment.currency);
        tvReference.setText(billPay.payment.reference);
      }

      tvStatus.setText(billPay.status.getLocalizedString(getActivity()));

      if (billPay.details != null) {
        String fee;
        if (billPay.details.fee != null) {
          fee = Utils.formatFiatValueAsString(billPay.details.fee) + " " + billPay.payment.currency;
        } else {
          fee = "???";
        }
        tvFee.setText(getResources().getString(R.string.cashila_fee, fee));

        // if there is already an amount deposited but still outstanding we have underpaid (maybe
        // because of some latency of
        // the bitcoin network and/or changes in exchange rate)

        BigDecimal amountDeposited =
            billPay.details.amountDeposited == null
                ? BigDecimal.ZERO
                : billPay.details.amountDeposited;
        BigDecimal amountToDeposit =
            billPay.details.amountToDeposit == null
                ? BigDecimal.ZERO
                : billPay.details.amountToDeposit;
        if (BigDecimal.ZERO.compareTo(amountDeposited) < 0
            && BigDecimal.ZERO.compareTo(amountToDeposit) < 0) {
          tvOutstandingAmount.setVisibility(View.VISIBLE);
          long satoshisOutstanding = Bitcoins.nearestValue(amountToDeposit).getLongValue();
          tvOutstandingAmount.setText(
              String.format(
                  getResources().getString(R.string.cashila_amount_outstanding),
                  mbw.getBtcValueString(satoshisOutstanding)));
        } else {
          tvOutstandingAmount.setVisibility(View.GONE);
        }
        tvDate.setText(Utils.getFormattedDate(getContext(), billPay.details.createdAt));
      }

      if (position == 0) {
        tvSectionHeader.setVisibility(View.VISIBLE);
      } else if (getItem(position - 1).getSortOrder() != billPay.getSortOrder()) {
        tvSectionHeader.setVisibility(View.VISIBLE);
      } else {
        tvSectionHeader.setVisibility(View.GONE);
      }
      if (billPay.isPayable()) {
        tvSectionHeader.setText(getResources().getString(R.string.cashila_pending));
      } else if (billPay.status.equals(BillPayStatus.uploaded)) {
        tvSectionHeader.setText(getResources().getString(R.string.cashila_uploaded_title));
      } else {
        tvSectionHeader.setText(getResources().getString(R.string.cashila_done));
      }

      final ActionBarActivity actionBarActivity = (ActionBarActivity) getActivity();

      final RelativeLayout rlReference = ButterKnife.findById(convertView, R.id.rlReference);
      convertView.setOnClickListener(
          new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              currentActionMode =
                  actionBarActivity.startSupportActionMode(
                      new ActionMode.Callback() {
                        @Override
                        public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
                          if (billPay.isPayable()) {
                            actionMode
                                .getMenuInflater()
                                .inflate(R.menu.ext_cashila_pending_payments_menu, menu);
                            currentActionMode = actionMode;
                          }
                          rlReference.setVisibility(View.VISIBLE);
                          lvPending.setItemChecked(position, true);
                          return true;
                        }

                        @Override
                        public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
                          rlReference.setVisibility(View.VISIBLE);
                          return billPay.isPayable();
                        }

                        @Override
                        public boolean onActionItemClicked(
                            ActionMode actionMode, MenuItem menuItem) {
                          final int itemId = menuItem.getItemId();
                          if (itemId == R.id.miDeletePayment) {
                            deletePayment(billPay);
                            return true;
                          } else if (itemId == R.id.miPayNow) {
                            payNow(billPay);
                            return true;
                          }

                          return false;
                        }

                        @Override
                        public void onDestroyActionMode(ActionMode actionMode) {
                          lvPending.setItemChecked(position, false);
                          rlReference.setVisibility(View.GONE);
                          currentActionMode = null;
                        }
                      });
            }
          });

      return convertView;
    }
예제 #20
0
  public ElectronicInvoiceRejectItem(
      ElectronicInvoiceRejectDocument electronicInvoiceRejectDocument, ElectronicInvoiceItem eii) {
    super();

    this.electronicInvoiceRejectDocument = electronicInvoiceRejectDocument;
    try {
      this.invoiceItemLineNumber = new Integer(Integer.parseInt(eii.getInvoiceLineNumber()));
    } catch (NumberFormatException n) {
      this.invoiceItemLineNumber = null;
    }
    this.invoiceItemCatalogNumber = eii.getCatalogNumber();
    this.invoiceItemQuantity = eii.getInvoiceLineQuantityBigDecimal();
    this.invoiceItemUnitOfMeasureCode = eii.getUnitOfMeasure();
    this.invoiceReferenceItemLineNumber = eii.getReferenceLineNumberInteger();
    this.invoiceReferenceItemSerialNumber = eii.getReferenceSerialNumber();
    this.invoiceReferenceItemSupplierPartIdentifier = eii.getReferenceItemIDSupplierPartID();
    this.invoiceReferenceItemSupplierPartAuxiliaryIdentifier =
        eii.getReferenceItemIDSupplierPartAuxID();
    this.invoiceReferenceItemDescription = eii.getReferenceDescription();
    this.invoiceReferenceItemManufacturerPartIdentifier = eii.getReferenceManufacturerPartID();
    this.invoiceReferenceItemManufacturerName = eii.getReferenceManufacturerName();
    this.invoiceReferenceItemCountryCode = eii.getReferenceCountryCode();
    this.invoiceReferenceItemCountryName = eii.getReferenceCountryName();

    this.invoiceItemUnitPriceCurrencyCode = eii.getUnitPriceCurrency();
    this.invoiceItemSubTotalCurrencyCode = eii.getSubTotalAmountCurrency();
    this.invoiceItemSpecialHandlingCurrencyCode = eii.getInvoiceLineSpecialHandlingAmountCurrency();
    this.invoiceItemShippingCurrencyCode = eii.getInvoiceLineShippingAmountCurrency();
    this.invoiceItemShippingDescription = eii.getInvoiceLineShippingDescription();
    this.invoiceItemTaxCurrencyCode = eii.getTaxAmountCurrency();
    this.invoiceItemTaxDescription = eii.getTaxDescription();
    this.invoiceItemGrossCurrencyCode = eii.getInvoiceLineGrossAmountCurrency();
    this.invoiceItemDiscountCurrencyCode = eii.getInvoiceLineDiscountAmountCurrency();
    this.invoiceItemNetCurrencyCode = eii.getInvoiceLineNetAmountCurrency();

    this.invoiceItemUnitPrice = eii.getInvoiceLineUnitCostBigDecimal();
    this.invoiceItemSubTotalAmount = eii.getInvoiceLineSubTotalAmountBigDecimal();
    this.invoiceItemSpecialHandlingAmount = eii.getInvoiceLineSpecialHandlingAmountBigDecimal();
    this.invoiceItemShippingAmount = eii.getInvoiceLineShippingAmountBigDecimal();
    this.invoiceItemTaxAmount = eii.getInvoiceLineTaxAmountBigDecimal();
    this.invoiceItemGrossAmount = eii.getInvoiceLineGrossAmountBigDecimal();
    this.invoiceItemDiscountAmount = eii.getInvoiceLineDiscountAmountBigDecimal();
    this.invoiceItemNetAmount = eii.getInvoiceLineNetAmountBigDecimal();

    // setup the sub total amount so that the reject prints to the files correctly
    if (((eii.getSubTotalAmount() == null) || ("".equals(eii.getSubTotalAmount())))) {
      // the sub total amount of this electronic invoice item was not given
      if (((this.invoiceItemQuantity != null)
              && ((BigDecimal.ZERO.compareTo(this.invoiceItemQuantity)) != 0))
          && ((this.invoiceItemUnitPrice != null)
              && ((BigDecimal.ZERO.compareTo(this.invoiceItemUnitPrice)) != 0))) {
        // unit price and quantity are valid... calculate subtotal
        this.invoiceItemSubTotalAmount =
            this.invoiceItemQuantity.multiply(this.invoiceItemUnitPrice);
      } else if (((this.invoiceItemQuantity == null) || ("".equals(this.invoiceItemQuantity)))
          && ((this.invoiceItemUnitPrice != null)
              && ((BigDecimal.ZERO.compareTo(this.invoiceItemUnitPrice)) != 0))) {
        // quantity is empty but unit cost exists... use it
        this.invoiceItemSubTotalAmount = this.invoiceItemUnitPrice;
      } else {
        this.invoiceItemSubTotalAmount = null;
      }
    } else {
      this.invoiceItemSubTotalAmount = eii.getInvoiceLineSubTotalAmountBigDecimal();
    }
  }
  public boolean isApplicable(InvoiceDTO invoice, BillingProcessDTO process) throws TaskException {

    return BigDecimal.ZERO.compareTo(invoice.getBalance()) > 0;
  }
예제 #22
0
  public InvoiceDTO[] generateInvoice(
      BillingProcessDTO process, UserDTO user, boolean isReview, boolean onlyRecurring)
      throws SessionInternalError {

    Integer userId = user.getUserId();
    Integer entityId = user.getEntity().getId();

    // get the configuration
    boolean useProcessDateForInvoice = true;
    int maximumPeriods = 1;
    boolean paymentApplication = false;
    try {
      ConfigurationBL config = new ConfigurationBL(process.getEntity().getId());
      useProcessDateForInvoice = config.getEntity().getInvoiceDateProcess() == 1;
      maximumPeriods = config.getEntity().getMaximumPeriods();
      paymentApplication = config.getEntity().getAutoPaymentApplication() == 1;
    } catch (Exception e) {
      // swallow exception
    }

    // this contains the generated invoices, one per due date
    // found in the applicable purchase orders.
    // The key is the object TimePeriod
    Hashtable<TimePeriod, NewInvoiceDTO> newInvoices = new Hashtable<TimePeriod, NewInvoiceDTO>();
    InvoiceDTO[] retValue = null;

    LOG.debug(
        "In generateInvoice for user " + userId + " process date:" + process.getBillingDate());

    /*
     * Go through the orders first
     * This method will recursively call itself to find sub-accounts in any
     * level
     */
    boolean includedOrders =
        processOrdersForUser(
            user,
            entityId,
            process,
            isReview,
            onlyRecurring,
            useProcessDateForInvoice,
            maximumPeriods,
            newInvoices);

    if (!includedOrders || newInvoices.size() == 0) {
      // check if invoices without orders are allowed
      PreferenceBL preferenceBL = new PreferenceBL();
      try {
        preferenceBL.set(entityId, Constants.PREFERENCE_ALLOW_INVOICES_WITHOUT_ORDERS);
      } catch (EmptyResultDataAccessException fe) {
        // use default
      }

      if (preferenceBL.getInt() == 0) {
        LOG.debug("No applicable orders. No invoice generated (skipping invoices).");
        return null;
      }
    }

    if (!isReview) {
      for (Map.Entry<TimePeriod, NewInvoiceDTO> newInvoiceEntry : newInvoices.entrySet()) {
        // process events before orders added to invoice
        processOrderToInvoiceEvents(newInvoiceEntry.getValue(), entityId);
      }
    }

    /*
     * Include those invoices that should've been paid
     * (or have negative balance, as credits)
     */
    LOG.debug("Considering overdue invoices");
    // find the invoice home interface
    InvoiceDAS invoiceDas = new InvoiceDAS();
    // any of the new invoices being created could hold the overdue invoices
    NewInvoiceDTO holder =
        newInvoices.isEmpty() ? null : (NewInvoiceDTO) newInvoices.elements().nextElement();

    Collection dueInvoices = invoiceDas.findWithBalanceByUser(user);
    LOG.debug("Processing invoices for user " + user.getUserId());
    // go through each of them, and update the DTO if it applies

    for (Iterator it = dueInvoices.iterator(); it.hasNext(); ) {
      InvoiceDTO invoice = (InvoiceDTO) it.next();
      if (invoice.getToProcess() == InvoiceDTO.DO_NOT_PROCESS) {
        LOG.debug("skipping invoice " + invoice.getId() + " because DO_NOT_PROCESS is set");
        continue;
      }
      LOG.debug("Processing invoice " + invoice.getId());
      // apply any invoice processing filter pluggable task
      try {
        PluggableTaskManager taskManager =
            new PluggableTaskManager(entityId, Constants.PLUGGABLE_TASK_INVOICE_FILTER);
        InvoiceFilterTask task = (InvoiceFilterTask) taskManager.getNextClass();
        boolean isProcessable = true;
        while (task != null) {
          isProcessable = task.isApplicable(invoice, process);
          if (!isProcessable) {
            break; // no need to keep doing more tests
          }
          task = (InvoiceFilterTask) taskManager.getNextClass();
        }

        // include this invoice only if it complies with all the rules
        if (isProcessable) {
          // check for an invoice
          if (holder == null) {
            // Since there are no new invoices (therefore no orders),
            // don't let invoices with positive balances generate
            // an invoice.
            if (BigDecimal.ZERO.compareTo(invoice.getBalance()) < 0) {
              continue;
            }

            // no invoice/s yet (no applicable orders), so create one
            holder = new NewInvoiceDTO();
            holder.setDate(process.getBillingDate());
            holder.setIsReview(isReview ? new Integer(1) : new Integer(0));
            holder.setCarriedBalance(BigDecimal.ZERO);
            holder.setInvoiceStatus(new InvoiceStatusDAS().find(Constants.INVOICE_STATUS_UNPAID));

            // need to set a due date, so use the order default
            OrderBL orderBl = new OrderBL();
            OrderDTO order = new OrderDTO();
            order.setBaseUserByUserId(user);
            orderBl.set(order);
            TimePeriod dueDatePeriod = orderBl.getDueDate();

            holder.setDueDatePeriod(dueDatePeriod);
            newInvoices.put(dueDatePeriod, holder);
          }

          InvoiceBL ibl = new InvoiceBL(invoice);
          holder.addInvoice(ibl.getDTO());
          // for those invoices wiht only overdue invoices, the
          // currency has to be initialized

          if (holder.getCurrency() == null) {
            holder.setCurrency(invoice.getCurrency());
          } else if (holder.getCurrency().getId() != invoice.getCurrency().getId()) {
            throw new SessionInternalError(
                "An invoice with different "
                    + "currency is not supported. "
                    + "Currency = "
                    + holder.getCurrency().getId()
                    + "invoice = "
                    + invoice.getId());
          }
          // update the amount of the new invoice that is due to
          // previously unpaid overdue invoices

          // carry the remaining balance, plus the previously carried balance to the new invoice
          BigDecimal balance =
              (invoice.getBalance() == null) ? BigDecimal.ZERO : invoice.getBalance();
          BigDecimal carried = balance.add(holder.getCarriedBalance());
          holder.setCarriedBalance(carried);
        }

        LOG.debug("invoice " + invoice.getId() + " result " + isProcessable);

      } catch (PluggableTaskException e) {
        LOG.fatal("Problems handling task invoice filter.", e);
        throw new SessionInternalError("Problems handling task invoice filter.");
      } catch (TaskException e) {
        LOG.fatal("Problems excecuting task invoice filter.", e);
        throw new SessionInternalError("Problems executing task invoice filter.");
      }
    }

    if (newInvoices.size() == 0) {
      // no orders or invoices for this invoice
      LOG.debug("No applicable orders or invoices. No invoice generated (skipping invoices).");
      return null;
    }

    try {
      retValue = new InvoiceDTO[newInvoices.size()];
      int index = 0;
      for (NewInvoiceDTO invoice : newInvoices.values()) {
        LOG.debug(
            "Processing invoice "
                + invoice.getId()
                + " "
                + invoice.getBalance()
                + " "
                + invoice.getTotal());
        /*
         * Apply invoice composition tasks to the new invoices object
         */
        composeInvoice(entityId, user.getUserId(), invoice);

        LOG.debug(
            "  after composeInvoice "
                + invoice.getId()
                + " "
                + invoice.getBalance()
                + " "
                + invoice.getTotal());
        if (!isReview) {
          // process events after orders added to invoice
          processOrderAddedOnInvoiceEvents(invoice, entityId);
          LOG.debug("processing old invoices");
          for (InvoiceDTO oldInvoice : invoice.getInvoices()) {
            // since this invoice is being delegated, mark it as being carried forward
            // so that it is not re-processed later. do not clear the old balance!
            LOG.debug(
                "  setting status unpaid and carried on "
                    + oldInvoice.getId()
                    + " "
                    + oldInvoice.getBalance()
                    + " "
                    + oldInvoice.getTotal());
            oldInvoice.setInvoiceStatus(
                new InvoiceStatusDAS().find(Constants.INVOICE_STATUS_UNPAID_AND_CARRIED));
          }
        }

        /*
         * apply this object to the DB, generating the actual rows
         */
        // only if the invoice generated actually has some lines in it
        if (invoice.areLinesGeneratedEmpty()) {
          LOG.warn(
              "User "
                  + user.getUserId()
                  + " had orders or invoices but"
                  + " the invoice composition task didn't generate any lines.");
          continue;
        }

        // If this is a web services API call, the billing
        // process id is 0. Don't link to the billing process
        // object for API calls.
        retValue[index] =
            generateDBInvoice(
                user.getUserId(),
                invoice,
                (process.getId() != 0 ? process : null),
                Constants.ORDER_PROCESS_ORIGIN_PROCESS);

        // try to get this new invioce paid by previously unlinked
        // payments
        if (paymentApplication && !isReview) {
          PaymentBL pBL = new PaymentBL();
          pBL.automaticPaymentApplication(retValue[index]);
        }

        index++;
      }
    } catch (PluggableTaskException e1) {
      LOG.error("Error handling pluggable tasks when composing an invoice");
      throw new SessionInternalError(e1);
    } catch (TaskException e1) {
      LOG.error("Task exception when composing an invoice");
      throw new SessionInternalError(e1);
    } catch (Exception e1) {
      LOG.error("Error, probably linking payments", e1);
      throw new SessionInternalError(e1);
    }

    InvoicesGeneratedEvent generatedEvent = new InvoicesGeneratedEvent(entityId, process.getId());
    generatedEvent.addInvoices(retValue);
    EventManager.process(generatedEvent);

    return retValue;
  }
예제 #23
0
 private boolean determineIfFullyPaid() {
   if (this.amount == null) {
     return true;
   }
   return BigDecimal.ZERO.compareTo(calculateOutstanding()) == 0;
 }
예제 #24
0
  private void moveResources(
      Entity warehouseFrom,
      Entity warehouseTo,
      Entity position,
      Object date,
      WarehouseAlgorithm warehouseAlgorithm) {
    Entity product = position.getBelongsToField(PositionFields.PRODUCT);

    List<Entity> resources =
        getResourcesForWarehouseProductAndAlgorithm(
            warehouseFrom, product, position, warehouseAlgorithm);

    BigDecimal quantity = position.getDecimalField(PositionFields.QUANTITY);

    resourceStockService.removeResourceStock(product, warehouseFrom, quantity);
    for (Entity resource : resources) {
      BigDecimal resourceQuantity = resource.getDecimalField(QUANTITY);

      BigDecimal resourceAvailableQuantity =
          resource.getDecimalField(ResourceFields.AVAILABLE_QUANTITY);
      if (quantity.compareTo(resourceAvailableQuantity) >= 0) {
        quantity = quantity.subtract(resourceAvailableQuantity, numberService.getMathContext());
        if (resourceQuantity.compareTo(resourceAvailableQuantity) <= 0) {
          resource.getDataDefinition().delete(resource.getId());
        } else {
          BigDecimal newResourceQuantity = resourceQuantity.subtract(resourceAvailableQuantity);
          BigDecimal resourceConversion = resource.getDecimalField(ResourceFields.CONVERSION);
          BigDecimal quantityInAdditionalUnit = newResourceQuantity.multiply(resourceConversion);
          resource.setField(ResourceFields.AVAILABLE_QUANTITY, BigDecimal.ZERO);
          resource.setField(ResourceFields.QUANTITY, newResourceQuantity);
          resource.setField(
              ResourceFields.QUANTITY_IN_ADDITIONAL_UNIT,
              numberService.setScale(quantityInAdditionalUnit));
          resource.getDataDefinition().save(resource);
        }

        createResource(position, warehouseTo, resource, resourceAvailableQuantity, date);

        if (BigDecimal.ZERO.compareTo(quantity) == 0) {
          return;
        }
      } else {
        resourceQuantity = resourceQuantity.subtract(quantity, numberService.getMathContext());
        resourceAvailableQuantity =
            resourceAvailableQuantity.subtract(quantity, numberService.getMathContext());
        String givenUnit = resource.getStringField(ResourceFields.GIVEN_UNIT);
        BigDecimal quantityInAdditionalUnit =
            convertToGivenUnit(resourceQuantity, product, givenUnit);

        resource.setField(
            ResourceFields.QUANTITY_IN_ADDITIONAL_UNIT,
            numberService.setScale(quantityInAdditionalUnit));
        resource.setField(ResourceFields.QUANTITY, numberService.setScale(resourceQuantity));
        resource.setField(ResourceFields.AVAILABLE_QUANTITY, resourceAvailableQuantity);

        resource.getDataDefinition().save(resource);

        createResource(position, warehouseTo, resource, quantity, date);

        return;
      }
    }

    position.addError(
        position.getDataDefinition().getField(PositionFields.QUANTITY),
        "materialFlow.error.position.quantity.notEnough");
  }
예제 #25
0
  private List<Entity> updateResources(
      Entity warehouse, Entity position, WarehouseAlgorithm warehouseAlgorithm) {
    DataDefinition positionDD =
        dataDefinitionService.get(
            MaterialFlowResourcesConstants.PLUGIN_IDENTIFIER,
            MaterialFlowResourcesConstants.MODEL_POSITION);

    List<Entity> newPositions = Lists.newArrayList();

    Entity product = position.getBelongsToField(PositionFields.PRODUCT);

    List<Entity> resources =
        getResourcesForWarehouseProductAndAlgorithm(
            warehouse, product, position, warehouseAlgorithm);

    BigDecimal quantity = position.getDecimalField(PositionFields.QUANTITY);

    resourceStockService.removeResourceStock(product, warehouse, quantity);
    for (Entity resource : resources) {
      BigDecimal resourceQuantity = resource.getDecimalField(ResourceFields.QUANTITY);
      BigDecimal resourceAvailableQuantity =
          resource.getDecimalField(ResourceFields.AVAILABLE_QUANTITY);

      Entity newPosition = positionDD.create();

      newPosition.setField(
          PositionFields.PRODUCT, position.getBelongsToField(PositionFields.PRODUCT));
      newPosition.setField(
          PositionFields.GIVEN_QUANTITY, position.getDecimalField(PositionFields.GIVEN_QUANTITY));
      newPosition.setField(
          PositionFields.GIVEN_UNIT, position.getStringField(PositionFields.GIVEN_UNIT));
      newPosition.setField(PositionFields.PRICE, resource.getField(ResourceFields.PRICE));
      newPosition.setField(PositionFields.BATCH, resource.getField(ResourceFields.BATCH));
      newPosition.setField(
          PositionFields.PRODUCTION_DATE, resource.getField(ResourceFields.PRODUCTION_DATE));
      newPosition.setField(
          PositionFields.EXPIRATION_DATE, resource.getField(ResourceFields.EXPIRATION_DATE));
      newPosition.setField(PositionFields.RESOURCE, resource);
      newPosition.setField(
          PositionFields.STORAGE_LOCATION, resource.getField(ResourceFields.STORAGE_LOCATION));
      newPosition.setField(
          PositionFields.ADDITIONAL_CODE, resource.getField(ResourceFields.ADDITIONAL_CODE));
      newPosition.setField(PositionFields.CONVERSION, position.getField(PositionFields.CONVERSION));
      newPosition.setField(
          PositionFields.PALLET_NUMBER, resource.getField(ResourceFields.PALLET_NUMBER));
      newPosition.setField(
          PositionFields.TYPE_OF_PALLET, resource.getField(ResourceFields.TYPE_OF_PALLET));
      // newPosition.setField(PositionFields.GIVEN_UNIT,
      // resource.getField(ResourceFields.GIVEN_UNIT));

      setPositionAttributesFromResource(newPosition, resource);

      if (quantity.compareTo(resourceAvailableQuantity) >= 0) {
        quantity = quantity.subtract(resourceAvailableQuantity, numberService.getMathContext());
        if (resourceQuantity.compareTo(resourceAvailableQuantity) <= 0) {
          resource.getDataDefinition().delete(resource.getId());
        } else {
          BigDecimal newResourceQuantity = resourceQuantity.subtract(resourceAvailableQuantity);
          BigDecimal resourceConversion = resource.getDecimalField(ResourceFields.CONVERSION);
          BigDecimal quantityInAdditionalUnit = newResourceQuantity.multiply(resourceConversion);
          resource.setField(ResourceFields.AVAILABLE_QUANTITY, BigDecimal.ZERO);
          resource.setField(ResourceFields.QUANTITY, newResourceQuantity);
          resource.setField(
              ResourceFields.QUANTITY_IN_ADDITIONAL_UNIT,
              numberService.setScale(quantityInAdditionalUnit));
          resource.getDataDefinition().save(resource);
        }

        newPosition.setField(
            PositionFields.QUANTITY, numberService.setScale(resourceAvailableQuantity));

        BigDecimal givenResourceQuantity = convertToGivenUnit(resourceAvailableQuantity, position);

        newPosition.setField(
            PositionFields.GIVEN_QUANTITY, numberService.setScale(givenResourceQuantity));

        newPositions.add(newPosition);

        if (BigDecimal.ZERO.compareTo(quantity) == 0) {
          return newPositions;
        }
      } else {
        resourceQuantity = resourceQuantity.subtract(quantity, numberService.getMathContext());
        resourceAvailableQuantity =
            resourceAvailableQuantity.subtract(quantity, numberService.getMathContext());
        if (position.getBelongsToField(PositionFields.RESOURCE) != null
            && reservationsService.reservationsEnabledForDocumentPositions()) {
          BigDecimal reservedQuantity =
              resource
                  .getDecimalField(ResourceFields.RESERVED_QUANTITY)
                  .subtract(quantity, numberService.getMathContext());
          resource.setField(ResourceFields.RESERVED_QUANTITY, reservedQuantity);
        }
        BigDecimal resourceConversion = resource.getDecimalField(ResourceFields.CONVERSION);
        BigDecimal quantityInAdditionalUnit = resourceQuantity.multiply(resourceConversion);

        resource.setField(
            ResourceFields.QUANTITY_IN_ADDITIONAL_UNIT,
            numberService.setScale(quantityInAdditionalUnit));
        resource.setField(ResourceFields.QUANTITY, numberService.setScale(resourceQuantity));
        resource.setField(ResourceFields.AVAILABLE_QUANTITY, resourceAvailableQuantity);

        resource.getDataDefinition().save(resource);
        newPosition.setField(PositionFields.QUANTITY, numberService.setScale(quantity));

        BigDecimal givenQuantity = convertToGivenUnit(quantity, position);

        newPosition.setField(PositionFields.GIVEN_QUANTITY, numberService.setScale(givenQuantity));
        newPositions.add(newPosition);

        return newPositions;
      }
    }

    position.addError(
        position.getDataDefinition().getField(PositionFields.QUANTITY),
        "materialFlow.error.position.quantity.notEnough");

    return Lists.newArrayList(position);
  }