@Test public void withSmallNetAmount() { invoiceItem.setNetAmount(new BigDecimal("1.50")); invoiceItem.verify(); assertThat(invoiceItem.getVatAmount(), is(new BigDecimal("0.26"))); assertThat(invoiceItem.getGrossAmount(), is(new BigDecimal("1.76"))); }
@Test public void withLargeNetAmount() { invoiceItem.setNetAmount(new BigDecimal("100.00")); invoiceItem.verify(); assertThat(invoiceItem.getVatAmount(), is(new BigDecimal("17.50"))); assertThat(invoiceItem.getGrossAmount(), is(new BigDecimal("117.50"))); }
@Test public void withNullTax() { invoiceItem.setTax(null); invoiceItem.setNetAmount(new BigDecimal("1.50")); invoiceItem.verify(); assertThat(invoiceItem.getVatAmount(), is(new BigDecimal("0"))); assertThat(invoiceItem.getGrossAmount(), is(new BigDecimal("1.50"))); }
private InvoiceItem newInvoiceItem( Invoice invoice, LocalDate startDate, Charge charge, String description) { final InvoiceItem ii = new InvoiceItemForTesting(); ii.setInvoice(invoice); ii.setStartDate(startDate); ii.setCharge(charge); ii.setDescription(description); return ii; }
/** * Create an adjustment for a given invoice item. This just creates the object in memory, it * doesn't write it to disk. * * @param invoiceToBeAdjusted the invoice * @param invoiceItemId the invoice item id to adjust * @param positiveAdjAmount the amount to adjust. Pass null to adjust the full amount of the * original item * @param currency the currency of the amount. Pass null to default to the original currency used * @param effectiveDate adjustment effective date, in the account timezone * @return the adjustment item */ public InvoiceItem createAdjustmentItem( final Invoice invoiceToBeAdjusted, final UUID invoiceItemId, @Nullable final BigDecimal positiveAdjAmount, @Nullable final Currency currency, final LocalDate effectiveDate, final InternalCallContext context) throws InvoiceApiException { final InvoiceItem invoiceItemToBeAdjusted = Iterables.<InvoiceItem>tryFind( invoiceToBeAdjusted.getInvoiceItems(), new Predicate<InvoiceItem>() { @Override public boolean apply(final InvoiceItem input) { return input.getId().equals(invoiceItemId); } }) .orNull(); if (invoiceItemToBeAdjusted == null) { throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_NOT_FOUND, invoiceItemId); } // Check the specified currency matches the one of the existing invoice final Currency currencyForAdjustment = Objects.firstNonNull(currency, invoiceItemToBeAdjusted.getCurrency()); if (invoiceItemToBeAdjusted.getCurrency() != currencyForAdjustment) { throw new InvoiceApiException( ErrorCode.CURRENCY_INVALID, currency, invoiceItemToBeAdjusted.getCurrency()); } // Reuse the same logic we have for refund with item adjustment final Map<UUID, BigDecimal> input = new HashMap<UUID, BigDecimal>(); input.put(invoiceItemId, positiveAdjAmount); final Map<UUID, BigDecimal> output = dao.computeItemAdjustments(invoiceToBeAdjusted.getId().toString(), input, context); // If we pass that stage, it means the validation succeeded so we just need to extract resulting // amount and negate the result. final BigDecimal amountToAdjust = output.get(invoiceItemId).negate(); // Finally, create the adjustment return new ItemAdjInvoiceItem( UUIDs.randomUUID(), context.getCreatedDate(), invoiceItemToBeAdjusted.getInvoiceId(), invoiceItemToBeAdjusted.getAccountId(), effectiveDate, null, amountToAdjust, currencyForAdjustment, invoiceItemToBeAdjusted.getId()); }
@Before public void setup() { context.checking( new Expectations() { { allowing(mockTax) .percentageFor(with(anyOf(aNull(LocalDate.class), any(LocalDate.class)))); will(returnValue(new BigDecimal("17.5"))); } }); invoiceItem = new InvoiceItem() { public ApplicationTenancy getApplicationTenancy() { return null; } }; invoiceItem.setTax(mockTax); }
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { try { int clientReference = new Integer(request.getParameter("clientReference")); OnlineClient onlineClient = OnlineClients.instance().get(clientReference); response.setCharacterEncoding("utf-8"); response.setContentType("application/json"); if (!onlineClient.isAuthenticated(request) && !(onlineClient.hasAccess(AccessPermission.INVOICE_CANCEL) || onlineClient.hasAccess(AccessPermission.ADMIN))) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.getWriter().write("acceso denegado"); } String argsParam = request.getParameter("args"); String args = URLDecoder.decode(argsParam, "utf-8").toUpperCase(); String invoiceREF = null; org.bson.Document oInvoice = null; Invoice invoice = null; String[] argsspl = null; if (!args.equals("")) { argsspl = args.split(" "); if (argsspl.length == 1) { invoiceREF = argsspl[0].toUpperCase(); oInvoice = new Mongoi().doFindOne(Mongoi.INVOICES, "{ \"reference\" : \"" + invoiceREF + "\" }"); if (oInvoice == null) { response.setStatus(HttpServletResponse.SC_BAD_REQUEST); response.getWriter().write("error: referencia no encontrada '" + argsspl[0] + "'"); return; } invoice = new Gson().fromJson(oInvoice.toJson(), InvoiceFM01.class); if (invoice.attemptToLog(LogKind.CANCEL).isAllowed()) { if (invoice.hasElectronicVersion()) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = null; Document document = null; try { builder = factory.newDocumentBuilder(); document = builder.parse( new InputSource(new StringReader(invoice.getElectronicVersion().getXml()))); } catch (Exception e) { e.printStackTrace(); } Node node = document.getElementsByTagName("tfd:TimbreFiscalDigital").item(0); Element e = (Element) node; String uuid = e.getAttribute("UUID"); System.out.println("UUID:" + uuid); GSettings g = GSettings.instance(); Rhino rhino = new Rhino( g.getKey("CERTIFICATE"), g.getKey("PRIVATE_KEY"), g.getKey("PRIVATE_KEY_PASS")); rhino.setOpenSSL(g.getKey("SSL")); String cancel = rhino.cancelar( g.getKey("INVOICE_CERTIFICATE_AUTHORITY_USER"), g.getKey("INVOICE_CERTIFICATE_AUTHORITY_PASS"), g.getKey("INVOICE_SENDER_TAX_CODE"), uuid); document = builder.parse(new ByteArrayInputStream(cancel.getBytes())); NodeList nlist = document.getElementsByTagName("codigo"); System.out.println("CANCEL RESPONSE: " + cancel); if (nlist.item(0).getTextContent().equals("0") || nlist.item(0).getTextContent().equals("-5")) { String xml = document.getElementsByTagName("xmlretorno").item(0).getTextContent(); new Mongoi() .doUpdate( Mongoi.INVOICES, "{ \"reference\" : \"" + invoiceREF + "\"}", "{ \"electronicVersion.cancelXml\" : \"" + StringEscapeUtils.unescapeXml(xml) + "\"}"); new Mongoi() .doUpdate( Mongoi.INVOICES, "{ \"reference\" : \"" + invoiceREF + "\"}", "{ \"electronicVersion.active\" : false }"); JGet.stringTofile( StringEscapeUtils.unescapeXml(xml), GSettings.get("TMP_FOLDER") + invoice.getReference() + "-CANCELADO.xml"); if (!invoice.getClient().getEmail().equals("")) { HotmailSend.send( "factura CANCELADA " + invoice.getReference(), "la factura con folio fiscal \n" + uuid + "\nha sido cancelada.\n" + GSettings.get("EMAIL_BODY"), invoice.getClient().getEmail().split(" ") /*, new String[]{ GSettings.get("TMP_FOLDER")+invoice.getReference()+"-CANCELADO.xml"}, new String[]{invoice.getReference()+"-CANCELADO.xml"} */); } if (!invoice.getAgent().getEmail().equals("")) { HotmailSend.send( "factura CANCELADA " + invoice.getReference(), "la factura con folio fiscal \n" + uuid + "\nha sido cancelada.\n" + GSettings.get("EMAIL_BODY"), invoice.getAgent().getEmail().split(" ") /*, new String[]{ GSettings.get("TMP_FOLDER")+invoice.getReference()+"-CANCELADO.xml"}, new String[]{invoice.getReference()+"-CANCELADO.xml"} */); } } else { response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE); response .getWriter() .write( "ERROR: " + document.getElementsByTagName("mensaje").item(0).getTextContent()); return; } } InvoiceLog log = new InvoiceLog( InvoiceLog.LogKind.CANCEL, true, onlineClient.getShopman().getLogin()); InvoiceLog closeLog = new InvoiceLog( InvoiceLog.LogKind.CLOSE, true, onlineClient.getShopman().getLogin()); new Mongoi() .doPush( Mongoi.INVOICES, "{ \"reference\" : \"" + invoiceREF + "\"}", "{\"logs\" : " + new Gson().toJson(log) + " }"); new Mongoi() .doPush( Mongoi.INVOICES, "{ \"reference\" : \"" + invoiceREF + "\"}", "{\"logs\" : " + new Gson().toJson(closeLog) + " }"); new Mongoi() .doUpdate( Mongoi.INVOICES, "{ \"reference\" : \"" + invoiceREF + "\"}", "{\"updated\" : " + closeLog.getDate() + " }"); float cashIn = 0; if (invoice.hasLog(LogKind.AGENT_PAYMENT)) cashIn = invoice.getAgentPayment(); float cashOut = invoice.getTotal() - invoice.getDebt(); TheBox.instance().plus(cashIn - cashOut); TheBox.instance() .addLog( new TheBoxLog( cashOut - cashIn, log.getDate(), invoice.getReference(), LogKind.CANCEL.toString(), onlineClient.getShopman().getLogin())); List<InvoiceItem> invoiceItems = invoice.getItems(); for (int i = 0; i < invoiceItems.size(); i++) { InvoiceItem item = invoiceItems.get(i); if (Inventory.exists(item) && !item.isDisabled()) Inventory.incrementStored(item); } String successResponse = "CANCELADO " + invoice.getReference() + ": se realizó entrada-salida en caja $" + cashIn + "-$" + cashOut + " --> $" + (cashIn - cashOut); response.getWriter().write("{ \"message\":\"" + successResponse + "\" }"); return; } else { System.out.println("error al intentar cancelar documento"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.getWriter().write(invoice.attemptToLog(LogKind.CANCEL).getMessage()); return; } } else { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response .getWriter() .write( "numero de parametros incorrecto, especifica la referencia de un solo documento"); return; } } else { response.setStatus(HttpServletResponse.SC_BAD_REQUEST); response.getWriter().write("error: define una referencia"); return; } } catch (Exception e) { e.printStackTrace(); } }