{"action":"created","comment":{"url":"https://api.github.com/repos/metasfresh/metasfresh/pulls/comments/243188927","pull_request_review_id":186890699,"id":243188927,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI0MzE4ODkyNw==","diff_hunk":"@@ -251,546 +229,537 @@ final boolean isCreditMemo()\n \n \t/**************************************************************************\n \t * Get Source Currency Balance - subtracts line and tax amounts from total - no rounding\n-\t * \n+\t *\n \t * @return positive amount, if total invoice is bigger than lines\n \t */\n \t@Override\n \tpublic BigDecimal getBalance()\n \t{\n-\t\tBigDecimal retValue = ZERO;\n-\t\tStringBuilder sb = new StringBuilder(\" [\");\n+\t\tBigDecimal retValue = BigDecimal.ZERO;\n+\n \t\t// Total\n \t\tretValue = retValue.add(getAmount(Doc.AMTTYPE_Gross));\n-\t\tsb.append(getAmount(Doc.AMTTYPE_Gross));\n+\n \t\t// - Header Charge\n \t\tretValue = retValue.subtract(getAmount(Doc.AMTTYPE_Charge));\n-\t\tsb.append(\"-\").append(getAmount(Doc.AMTTYPE_Charge));\n+\n \t\t// - Tax\n-\t\tfor (int i = 0; i < m_taxes.length; i++)\n+\t\tfor (final DocTax docTax : getTaxes())\n \t\t{\n-\t\t\tretValue = retValue.subtract(m_taxes[i].getTaxAmt());\n-\t\t\tsb.append(\"-\").append(m_taxes[i].getTaxAmt());\n+\t\t\tretValue = retValue.subtract(docTax.getTaxAmt());\n \t\t}\n+\n \t\t// - Lines\n-\t\tfor (int i = 0; i < p_lines.length; i++)\n+\t\tfor (final DocLine_Invoice line : getDocLines())\n \t\t{\n-\t\t\tretValue = retValue.subtract(p_lines[i].getAmtSource());\n-\t\t\tsb.append(\"-\").append(p_lines[i].getAmtSource());\n+\t\t\tretValue = retValue.subtract(line.getAmtSource());\n \t\t}\n-\t\tsb.append(\"]\");\n-\t\t//\n-\t\tlog.debug(toString() + \" Balance=\" + retValue + sb.toString());\n+\n \t\treturn retValue;\n-\t}   // getBalance\n+\t}\n \n \tfinal DocTax getDocTaxOrNull(final int taxId)\n \t{\n-\t\tfor (final DocTax docTax : m_taxes)\n+\t\treturn getTaxes()\n+\t\t\t\t.stream()\n+\t\t\t\t.filter(docTax -> docTax.getC_Tax_ID() == taxId)\n+\t\t\t\t.findFirst()\n+\t\t\t\t.orElse(null);\n+\t}\n+\n+\t@Override\n+\tpublic List<Fact> createFacts(final AcctSchema as)\n+\t{\n+\t\t// Cash based accounting\n+\t\tif (!as.isAccrual())\n \t\t{\n-\t\t\tif (docTax.getC_Tax_ID() == taxId)\n-\t\t\t{\n-\t\t\t\treturn docTax;\n-\t\t\t}\n+\t\t\tthrow newPostingException().setAcctSchema(as).setDetailMessage(\"Cash based accounting is not supported\");\n \t\t}\n \n-\t\treturn null;\n+\t\t// ** ARI, ARF\n+\t\tfinal String docBaseType = getDocumentType();\n+\t\tif (DOCTYPE_ARInvoice.equals(docBaseType)\n+\t\t\t\t|| DOCTYPE_ARProForma.equals(docBaseType))\n+\t\t{\n+\t\t\treturn createFacts_SalesInvoice(as);\n+\t\t}\n+\t\t// ARC\n+\t\telse if (DOCTYPE_ARCredit.equals(docBaseType))\n+\t\t{\n+\t\t\treturn createFacts_SalesCreditMemo(as);\n+\t\t}\n+\n+\t\t// ** API\n+\t\telse if (DOCTYPE_APInvoice.equals(docBaseType)\n+\t\t\t\t|| Constants.DOCBASETYPE_AEInvoice.equals(docBaseType)  // metas-ts: treating commission/salary invoice like AP invoice\n+\t\t\t\t|| Constants.DOCBASETYPE_AVIinvoice.equals(docBaseType))   // metas-ts: treating invoice for recurrent payment like AP invoice\n+\t\t{\n+\t\t\treturn createFacts_PurchaseInvoice(as);\n+\t\t}\n+\t\t// APC\n+\t\telse if (DOCTYPE_APCredit.equals(docBaseType))\n+\t\t{\n+\t\t\treturn createFacts_PurchaseCreditMemo(as);\n+\t\t}\n+\t\telse\n+\t\t{\n+\t\t\tthrow newPostingException()\n+\t\t\t\t\t.setAcctSchema(as)\n+\t\t\t\t\t.setPostingStatus(PostingStatus.Error)\n+\t\t\t\t\t.setDetailMessage(\"DocumentType unknown: \" + docBaseType);\n+\t\t}\n \t}\n \n \t/**\n-\t * Create Facts (the accounting logic) for\n-\t * ARI, ARC, ARF, API, APC.\n-\t * \n \t * <pre>\n \t *  ARI, ARF\n \t *      Receivables     DR\n \t *      Charge                  CR\n \t *      TaxDue                  CR\n \t *      Revenue                 CR\n-\t * \n-\t *  ARC\n-\t *      Receivables             CR\n-\t *      Charge          DR\n-\t *      TaxDue          DR\n-\t *      Revenue         RR\n-\t * \n-\t *  API\n-\t *      Payables                CR\n-\t *      Charge          DR\n-\t *      TaxCredit       DR\n-\t *      Expense         DR\n-\t * \n-\t *  APC\n-\t *      Payables        DR\n-\t *      Charge                  CR\n-\t *      TaxCredit               CR\n-\t *      Expense                 CR\n \t * </pre>\n-\t * \n-\t * @param as accounting schema\n-\t * @return Fact\n \t */\n-\t@Override\n-\tpublic List<Fact> createFacts(final MAcctSchema as)\n+\tprivate List<Fact> createFacts_SalesInvoice(final AcctSchema as)\n \t{\n-\t\t//\n \t\tfinal List<Fact> facts = new ArrayList<>();\n-\t\t// create Fact Header\n-\t\tFact fact = new Fact(this, as, Fact.POST_Actual)\n+\t\tfinal Fact fact = new Fact(this, as, PostingType.Actual)\n \t\t\t\t.setFactTrxLinesStrategy(PerDocumentFactTrxStrategy.instance);\n+\t\tfacts.add(fact);\n \n-\t\t// Cash based accounting\n-\t\tif (!as.isAccrual())\n+\t\tBigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);\n+\t\tBigDecimal serviceAmt = BigDecimal.ZERO;\n+\n+\t\t// Header Charge CR\n+\t\tfinal BigDecimal chargeAmt = getAmount(Doc.AMTTYPE_Charge);\n+\t\tif (chargeAmt != null && chargeAmt.signum() != 0)\n \t\t{\n-\t\t\treturn facts;\n+\t\t\tfact.createLine(null, getAccount(Doc.ACCTTYPE_Charge, as), getCurrencyId(), null, chargeAmt);\n \t\t}\n \n-\t\t// ** ARI, ARF\n-\t\tif (getDocumentType().equals(DOCTYPE_ARInvoice)\n-\t\t\t\t|| getDocumentType().equals(DOCTYPE_ARProForma))\n+\t\t// TaxDue CR\n+\t\tfor (final DocTax docTax : getTaxes())\n \t\t{\n-\t\t\tBigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);\n-\t\t\tBigDecimal serviceAmt = ZERO;\n-\n-\t\t\t// Header Charge CR\n-\t\t\tBigDecimal amt = getAmount(Doc.AMTTYPE_Charge);\n-\t\t\tif (amt != null && amt.signum() != 0)\n-\t\t\t\tfact.createLine(null, getAccount(Doc.ACCTTYPE_Charge, as),\n-\t\t\t\t\t\tgetC_Currency_ID(), null, amt);\n-\t\t\t// TaxDue CR\n-\t\t\tfor (int i = 0; i < m_taxes.length; i++)\n+\t\t\tfinal BigDecimal taxAmt = docTax.getTaxAmt();\n+\t\t\tif (taxAmt != null && taxAmt.signum() != 0)\n \t\t\t{\n-\t\t\t\tamt = m_taxes[i].getTaxAmt();\n-\t\t\t\tif (amt != null && amt.signum() != 0)\n+\t\t\t\tfinal FactLine tl = fact.createLine(null, docTax.getTaxDueAcct(as),\n+\t\t\t\t\t\tgetCurrencyId(), null, taxAmt);\n+\t\t\t\tif (tl != null)\n \t\t\t\t{\n-\t\t\t\t\tFactLine tl = fact.createLine(null, m_taxes[i].getAccount(DocTax.ACCTTYPE_TaxDue, as),\n-\t\t\t\t\t\t\tgetC_Currency_ID(), null, amt);\n-\t\t\t\t\tif (tl != null)\n-\t\t\t\t\t\ttl.setC_Tax_ID(m_taxes[i].getC_Tax_ID());\n+\t\t\t\t\ttl.setC_Tax_ID(docTax.getC_Tax_ID());\n \t\t\t\t}\n \t\t\t}\n-\t\t\t// Revenue CR\n-\t\t\tfor (int i = 0; i < p_lines.length; i++)\n+\t\t}\n+\n+\t\t// Revenue CR\n+\t\tfor (final DocLine_Invoice line : getDocLines())\n+\t\t{\n+\t\t\tBigDecimal lineAmt = line.getAmtSource();\n+\t\t\tBigDecimal dAmt = null;\n+\t\t\tif (as.isPostTradeDiscount())\n \t\t\t{\n-\t\t\t\tamt = p_lines[i].getAmtSource();\n-\t\t\t\tBigDecimal dAmt = null;\n-\t\t\t\tif (as.isTradeDiscountPosted())\n-\t\t\t\t{\n-\t\t\t\t\tBigDecimal discount = p_lines[i].getDiscount();\n-\t\t\t\t\tif (discount != null && discount.signum() != 0)\n-\t\t\t\t\t{\n-\t\t\t\t\t\tamt = amt.add(discount);\n-\t\t\t\t\t\tdAmt = discount;\n-\t\t\t\t\t\tfact.createLine(p_lines[i],\n-\t\t\t\t\t\t\t\tp_lines[i].getAccount(ProductCost.ACCTTYPE_P_TDiscountGrant, as),\n-\t\t\t\t\t\t\t\tgetC_Currency_ID(), dAmt, null);\n-\t\t\t\t\t}\n-\t\t\t\t}\n-\t\t\t\tfact.createLine(p_lines[i],\n-\t\t\t\t\t\tp_lines[i].getAccount(ProductCost.ACCTTYPE_P_Revenue, as),\n-\t\t\t\t\t\tgetC_Currency_ID(), null, amt);\n-\t\t\t\tif (!p_lines[i].isItem())\n+\t\t\t\tfinal BigDecimal discount = line.getDiscount();\n+\t\t\t\tif (discount != null && discount.signum() != 0)\n \t\t\t\t{\n-\t\t\t\t\tgrossAmt = grossAmt.subtract(amt);\n-\t\t\t\t\tserviceAmt = serviceAmt.add(amt);\n+\t\t\t\t\tlineAmt = lineAmt.add(discount);\n+\t\t\t\t\tdAmt = discount;\n+\t\t\t\t\tfact.createLine(line,\n+\t\t\t\t\t\t\tline.getAccount(ProductAcctType.TDiscountGrant, as),\n+\t\t\t\t\t\t\tgetCurrencyId(), dAmt, null);\n \t\t\t\t}\n \t\t\t}\n-\t\t\t// Set Locations\n-\t\t\tFactLine[] fLines = fact.getLines();\n-\t\t\tfor (int i = 0; i < fLines.length; i++)\n+\t\t\tfact.createLine(line,\n+\t\t\t\t\tline.getAccount(ProductAcctType.Revenue, as),\n+\t\t\t\t\tgetCurrencyId(), null, lineAmt);\n+\t\t\tif (!line.isItem())\n \t\t\t{\n-\t\t\t\tif (fLines[i] != null)\n-\t\t\t\t{\n-\t\t\t\t\tfLines[i].setLocationFromOrg(fLines[i].getAD_Org_ID(), true);      // from Loc\n-\t\t\t\t\tfLines[i].setLocationFromBPartner(getC_BPartner_Location_ID(), false);  // to Loc\n-\t\t\t\t}\n+\t\t\t\tgrossAmt = grossAmt.subtract(lineAmt);\n+\t\t\t\tserviceAmt = serviceAmt.add(lineAmt);\n \t\t\t}\n+\t\t}\n \n-\t\t\t// Receivables DR\n-\t\t\tint receivables_ID = getValidCombination_ID(Doc.ACCTTYPE_C_Receivable, as);\n-\t\t\tint receivablesServices_ID = getValidCombination_ID(Doc.ACCTTYPE_C_Receivable_Services, as);\n-\t\t\tif (m_allLinesItem || !as.isPostServices()\n-\t\t\t\t\t|| receivables_ID == receivablesServices_ID)\n-\t\t\t{\n-\t\t\t\tgrossAmt = getAmount(Doc.AMTTYPE_Gross);\n-\t\t\t\tserviceAmt = ZERO;\n-\t\t\t}\n-\t\t\telse if (m_allLinesService)\n-\t\t\t{\n-\t\t\t\tserviceAmt = getAmount(Doc.AMTTYPE_Gross);\n-\t\t\t\tgrossAmt = ZERO;\n-\t\t\t}\n-\t\t\n-\t\t\t// https://github.com/metasfresh/metasfresh/issues/4147\n-\t\t\t// we need this line later, even if it is zero\n+\t\t// Set Locations\n+\t\tfact.forEach(fl -> {\n+\t\t\tfl.setLocationFromOrg(fl.getAD_Org_ID(), true);      // from Loc\n+\t\t\tfl.setLocationFromBPartner(getC_BPartner_Location_ID(), false);  // to Loc\n+\t\t});\n+\n+\t\t// Receivables DR\n+\t\tfinal AccountId receivablesId = getValidCombinationId(Doc.ACCTTYPE_C_Receivable, as);\n+\t\tfinal AccountId receivablesServicesId = getValidCombinationId(Doc.ACCTTYPE_C_Receivable_Services, as);\n+\t\tif (m_allLinesItem\n+\t\t\t\t|| !as.isPostServices()\n+\t\t\t\t|| AccountId.equals(receivablesId, receivablesServicesId))\n+\t\t{\n+\t\t\tgrossAmt = getAmount(Doc.AMTTYPE_Gross);\n+\t\t\tserviceAmt = BigDecimal.ZERO;\n+\t\t}\n+\t\telse if (m_allLinesService)\n+\t\t{\n+\t\t\tserviceAmt = getAmount(Doc.AMTTYPE_Gross);\n+\t\t\tgrossAmt = BigDecimal.ZERO;\n+\t\t}\n+\n+\t\t// https://github.com/metasfresh/metasfresh/issues/4147\n+\t\t// we need this line later, even if it is zero\n+\t\tfact.createLine()\n+\t\t\t\t.setAccount(receivablesId)\n+\t\t\t\t.setAmtSource(getCurrencyId(), grossAmt, null)\n+\t\t\t\t.alsoAddZeroLine()\n+\t\t\t\t.buildAndAdd();\n+\t\tif (serviceAmt.signum() != 0)\n+\t\t{\n \t\t\tfact.createLine()\n-\t\t\t\t\t.setAccount(MAccount.get(getCtx(), receivables_ID))\n-\t\t\t\t\t.setAmtSource(getC_Currency_ID(),  grossAmt,null)\n+\t\t\t\t\t.setAccount(receivablesServicesId)\n+\t\t\t\t\t.setAmtSource(getCurrencyId(), serviceAmt, null)\n \t\t\t\t\t.alsoAddZeroLine()\n \t\t\t\t\t.buildAndAdd();\n-\t\t\tif (serviceAmt.signum() != 0)\n-\t\t\t{\n-\t\t\t\tfact.createLine(null, MAccount.get(getCtx(), receivablesServices_ID),\n-\t\t\t\t\t\tgetC_Currency_ID(), serviceAmt, null);\n-\t\t\t}\n \t\t}\n-\t\t// ARC\n-\t\telse if (getDocumentType().equals(DOCTYPE_ARCredit))\n+\n+\t\treturn facts;\n+\t}\n+\n+\t/**\n+\t * <pre>\n+\t *  ARC\n+\t *      Receivables             CR\n+\t *      Charge          DR\n+\t *      TaxDue          DR\n+\t *      Revenue         RR\n+\t * </pre>\n+\t */\n+\tprivate List<Fact> createFacts_SalesCreditMemo(final AcctSchema as)\n+\t{\n+\t\tfinal List<Fact> facts = new ArrayList<>();\n+\t\tfinal Fact fact = new Fact(this, as, PostingType.Actual);\n+\t\tfacts.add(fact);\n+\n+\t\tBigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);\n+\t\tBigDecimal serviceAmt = BigDecimal.ZERO;\n+\n+\t\t// Header Charge DR\n+\t\tfinal BigDecimal chargeAmt = getAmount(Doc.AMTTYPE_Charge);\n+\t\tif (chargeAmt != null && chargeAmt.signum() != 0)\n \t\t{\n-\t\t\tBigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);\n-\t\t\tBigDecimal serviceAmt = ZERO;\n-\n-\t\t\t// Header Charge DR\n-\t\t\tBigDecimal amt = getAmount(Doc.AMTTYPE_Charge);\n-\t\t\tif (amt != null && amt.signum() != 0)\n-\t\t\t\tfact.createLine(null, getAccount(Doc.ACCTTYPE_Charge, as),\n-\t\t\t\t\t\tgetC_Currency_ID(), amt, null);\n-\t\t\t// TaxDue DR\n-\t\t\tfor (int i = 0; i < m_taxes.length; i++)\n-\t\t\t{\n-\t\t\t\tamt = m_taxes[i].getTaxAmt();\n-\t\t\t\tif (amt != null && amt.signum() != 0)\n-\t\t\t\t{\n-\t\t\t\t\tFactLine tl = fact.createLine(null, m_taxes[i].getAccount(DocTax.ACCTTYPE_TaxDue, as),\n-\t\t\t\t\t\t\tgetC_Currency_ID(), amt, null);\n-\t\t\t\t\tif (tl != null)\n-\t\t\t\t\t\ttl.setC_Tax_ID(m_taxes[i].getC_Tax_ID());\n-\t\t\t\t}\n-\t\t\t}\n-\t\t\t// Revenue CR\n-\t\t\tfor (int i = 0; i < p_lines.length; i++)\n+\t\t\tfact.createLine(null, getAccount(Doc.ACCTTYPE_Charge, as),\n+\t\t\t\t\tgetCurrencyId(), chargeAmt, null);\n+\t\t}\n+\n+\t\t// TaxDue DR\n+\t\tfor (final DocTax docTax : getTaxes())\n+\t\t{\n+\t\t\tfinal BigDecimal taxAmt = docTax.getTaxAmt();\n+\t\t\tif (taxAmt != null && taxAmt.signum() != 0)\n \t\t\t{\n-\t\t\t\tamt = p_lines[i].getAmtSource();\n-\t\t\t\tBigDecimal dAmt = null;\n-\t\t\t\tif (as.isTradeDiscountPosted())\n-\t\t\t\t{\n-\t\t\t\t\tBigDecimal discount = p_lines[i].getDiscount();\n-\t\t\t\t\tif (discount != null && discount.signum() != 0)\n-\t\t\t\t\t{\n-\t\t\t\t\t\tamt = amt.add(discount);\n-\t\t\t\t\t\tdAmt = discount;\n-\t\t\t\t\t\tfact.createLine(p_lines[i],\n-\t\t\t\t\t\t\t\tp_lines[i].getAccount(ProductCost.ACCTTYPE_P_TDiscountGrant, as),\n-\t\t\t\t\t\t\t\tgetC_Currency_ID(), null, dAmt);\n-\t\t\t\t\t}\n-\t\t\t\t}\n-\t\t\t\tfact.createLine(p_lines[i],\n-\t\t\t\t\t\tp_lines[i].getAccount(ProductCost.ACCTTYPE_P_Revenue, as),\n-\t\t\t\t\t\tgetC_Currency_ID(), amt, null);\n-\t\t\t\tif (!p_lines[i].isItem())\n+\t\t\t\tfinal FactLine tl = fact.createLine(null, docTax.getTaxDueAcct(as),\n+\t\t\t\t\t\tgetCurrencyId(), taxAmt, null);\n+\t\t\t\tif (tl != null)\n \t\t\t\t{\n-\t\t\t\t\tgrossAmt = grossAmt.subtract(amt);\n-\t\t\t\t\tserviceAmt = serviceAmt.add(amt);\n+\t\t\t\t\ttl.setC_Tax_ID(docTax.getC_Tax_ID());\n \t\t\t\t}\n \t\t\t}\n-\t\t\t// Set Locations\n-\t\t\tFactLine[] fLines = fact.getLines();\n-\t\t\tfor (int i = 0; i < fLines.length; i++)\n+\t\t}\n+\t\t// Revenue CR\n+\t\tfor (final DocLine_Invoice line : getDocLines())\n+\t\t{\n+\t\t\tBigDecimal lineAmt = line.getAmtSource();\n+\t\t\tBigDecimal dAmt = null;\n+\t\t\tif (as.isPostTradeDiscount())\n \t\t\t{\n-\t\t\t\tif (fLines[i] != null)\n+\t\t\t\tfinal BigDecimal discount = line.getDiscount();\n+\t\t\t\tif (discount != null && discount.signum() != 0)\n \t\t\t\t{\n-\t\t\t\t\tfLines[i].setLocationFromOrg(fLines[i].getAD_Org_ID(), true);      // from Loc\n-\t\t\t\t\tfLines[i].setLocationFromBPartner(getC_BPartner_Location_ID(), false);  // to Loc\n+\t\t\t\t\tlineAmt = lineAmt.add(discount);\n+\t\t\t\t\tdAmt = discount;\n+\t\t\t\t\tfact.createLine(line,\n+\t\t\t\t\t\t\tline.getAccount(ProductAcctType.TDiscountGrant, as),\n+\t\t\t\t\t\t\tgetCurrencyId(), null, dAmt);\n \t\t\t\t}\n \t\t\t}\n-\t\t\t// Receivables CR\n-\t\t\tint receivables_ID = getValidCombination_ID(Doc.ACCTTYPE_C_Receivable, as);\n-\t\t\tint receivablesServices_ID = getValidCombination_ID(Doc.ACCTTYPE_C_Receivable_Services, as);\n-\t\t\tif (m_allLinesItem || !as.isPostServices()\n-\t\t\t\t\t|| receivables_ID == receivablesServices_ID)\n+\t\t\tfact.createLine(line,\n+\t\t\t\t\tline.getAccount(ProductAcctType.Revenue, as),\n+\t\t\t\t\tgetCurrencyId(), lineAmt, null);\n+\t\t\tif (!line.isItem())\n \t\t\t{\n-\t\t\t\tgrossAmt = getAmount(Doc.AMTTYPE_Gross);\n-\t\t\t\tserviceAmt = ZERO;\n+\t\t\t\tgrossAmt = grossAmt.subtract(lineAmt);\n+\t\t\t\tserviceAmt = serviceAmt.add(lineAmt);\n \t\t\t}\n-\t\t\telse if (m_allLinesService)\n-\t\t\t{\n-\t\t\t\tserviceAmt = getAmount(Doc.AMTTYPE_Gross);\n-\t\t\t\tgrossAmt = ZERO;\n-\t\t\t}\n-\t\t\t// https://github.com/metasfresh/metasfresh/issues/4147\n-\t\t\t// we need this line later, even if it is zero\n+\t\t}\n+\t\t// Set Locations\n+\t\tfact.forEach(fl -> {\n+\t\t\tfl.setLocationFromOrg(fl.getAD_Org_ID(), true);      // from Loc\n+\t\t\tfl.setLocationFromBPartner(getC_BPartner_Location_ID(), false);  // to Loc\n+\t\t});\n+\n+\t\t// Receivables CR\n+\t\tfinal AccountId receivablesId = getValidCombinationId(Doc.ACCTTYPE_C_Receivable, as);\n+\t\tfinal AccountId receivablesServicesId = getValidCombinationId(Doc.ACCTTYPE_C_Receivable_Services, as);\n+\t\tif (m_allLinesItem\n+\t\t\t\t|| !as.isPostServices()\n+\t\t\t\t|| AccountId.equals(receivablesId, receivablesServicesId))\n+\t\t{\n+\t\t\tgrossAmt = getAmount(Doc.AMTTYPE_Gross);\n+\t\t\tserviceAmt = BigDecimal.ZERO;\n+\t\t}\n+\t\telse if (m_allLinesService)\n+\t\t{\n+\t\t\tserviceAmt = getAmount(Doc.AMTTYPE_Gross);\n+\t\t\tgrossAmt = BigDecimal.ZERO;\n+\t\t}\n+\n+\t\t// https://github.com/metasfresh/metasfresh/issues/4147\n+\t\t// we need this line later, even if it is zero\n+\t\tfact.createLine()\n+\t\t\t\t.setAccount(receivablesId)\n+\t\t\t\t.setAmtSource(getCurrencyId(), null, grossAmt)\n+\t\t\t\t.alsoAddZeroLine()\n+\t\t\t\t.buildAndAdd();\n+\t\tif (serviceAmt.signum() != 0)\n+\t\t{\n \t\t\tfact.createLine()\n-\t\t\t\t\t.setAccount(MAccount.get(getCtx(), receivables_ID))\n-\t\t\t\t\t.setAmtSource(getC_Currency_ID(), null, grossAmt)\n+\t\t\t\t\t.setAccount(receivablesServicesId)\n+\t\t\t\t\t.setAmtSource(getCurrencyId(), null, serviceAmt)\n \t\t\t\t\t.alsoAddZeroLine()\n \t\t\t\t\t.buildAndAdd();\n-\t\t\tif (serviceAmt.signum() != 0)\n-\t\t\t{\n-\t\t\t\tfact.createLine(null, MAccount.get(getCtx(), receivablesServices_ID), getC_Currency_ID(), null, serviceAmt);\n-\t\t\t}\n \t\t}\n \n-\t\t// ** API\n-\t\telse if (getDocumentType().equals(DOCTYPE_APInvoice)\n-\t\t\t\t|| getDocumentType().equals(Constants.DOCBASETYPE_AEInvoice) // metas-ts: treating commission/salary invoice like AP invoice\n-\t\t\t\t|| getDocumentType().equals(Constants.DOCBASETYPE_AVIinvoice))  // metas-ts: treating invoice for recurrent payment like AP invoice\n-\t\t{\n-\t\t\tBigDecimal grossAmt = getAmount(Doc.AMTTYPE_Gross);\n-\t\t\tBigDecimal serviceAmt = ZERO;\n+\t\treturn facts;\n+\t}\n \n-\t\t\t// Charge DR\n-\t\t\tfact.createLine(null, getAccount(Doc.ACCTTYPE_Charge, as),\n-\t\t\t\t\tgetC_Currency_ID(), getAmount(Doc.AMTTYPE_Charge), null);\n-\t\t\t// TaxCredit DR\n-\t\t\tfor (int i = 0; i < m_taxes.length; i++)\n+\t/**\n+\t * <pre>\n+\t *  API\n+\t *      Payables                CR\n+\t *      Charge          DR\n+\t *      TaxCredit       DR\n+\t *      Expense         DR\n+\t * </pre>\n+\t */\n+\tprivate List<Fact> createFacts_PurchaseInvoice(final AcctSchema as)","path":"de.metas.acct.base/src/main/java-legacy/org/compiere/acct/Doc_Invoice.java","position":820,"original_position":820,"commit_id":"1690cd7216f4a6b4e6018f7d30ed66df9dbfedef","original_commit_id":"1690cd7216f4a6b4e6018f7d30ed66df9dbfedef","user":{"login":"codacy-bot","id":19940114,"node_id":"MDQ6VXNlcjE5OTQwMTE0","avatar_url":"https://avatars1.githubusercontent.com/u/19940114?v=4","gravatar_id":"","url":"https://api.github.com/users/codacy-bot","html_url":"https://github.com/codacy-bot","followers_url":"https://api.github.com/users/codacy-bot/followers","following_url":"https://api.github.com/users/codacy-bot/following{/other_user}","gists_url":"https://api.github.com/users/codacy-bot/gists{/gist_id}","starred_url":"https://api.github.com/users/codacy-bot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codacy-bot/subscriptions","organizations_url":"https://api.github.com/users/codacy-bot/orgs","repos_url":"https://api.github.com/users/codacy-bot/repos","events_url":"https://api.github.com/users/codacy-bot/events{/privacy}","received_events_url":"https://api.github.com/users/codacy-bot/received_events","type":"User","site_admin":false},"body":"![Codacy](https://app.codacy.com/assets/images/favicon.png) Issue found: [The method createFacts_PurchaseInvoice() has an NPath complexity of 630](https://app.codacy.com/app/metasfresh/metasfresh/pullRequest?prid=2738103)","created_at":"2018-12-20T08:35:47Z","updated_at":"2018-12-20T08:35:48Z","html_url":"https://github.com/metasfresh/metasfresh/pull/4836#discussion_r243188927","pull_request_url":"https://api.github.com/repos/metasfresh/metasfresh/pulls/4836","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/metasfresh/metasfresh/pulls/comments/243188927"},"html":{"href":"https://github.com/metasfresh/metasfresh/pull/4836#discussion_r243188927"},"pull_request":{"href":"https://api.github.com/repos/metasfresh/metasfresh/pulls/4836"}}},"pull_request":{"url":"https://api.github.com/repos/metasfresh/metasfresh/pulls/4836","id":238735039,"node_id":"MDExOlB1bGxSZXF1ZXN0MjM4NzM1MDM5","html_url":"https://github.com/metasfresh/metasfresh/pull/4836","diff_url":"https://github.com/metasfresh/metasfresh/pull/4836.diff","patch_url":"https://github.com/metasfresh/metasfresh/pull/4836.patch","issue_url":"https://api.github.com/repos/metasfresh/metasfresh/issues/4836","number":4836,"state":"open","locked":false,"title":"Gh478","user":{"login":"teosarca","id":1244701,"node_id":"MDQ6VXNlcjEyNDQ3MDE=","avatar_url":"https://avatars2.githubusercontent.com/u/1244701?v=4","gravatar_id":"","url":"https://api.github.com/users/teosarca","html_url":"https://github.com/teosarca","followers_url":"https://api.github.com/users/teosarca/followers","following_url":"https://api.github.com/users/teosarca/following{/other_user}","gists_url":"https://api.github.com/users/teosarca/gists{/gist_id}","starred_url":"https://api.github.com/users/teosarca/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/teosarca/subscriptions","organizations_url":"https://api.github.com/users/teosarca/orgs","repos_url":"https://api.github.com/users/teosarca/repos","events_url":"https://api.github.com/users/teosarca/events{/privacy}","received_events_url":"https://api.github.com/users/teosarca/received_events","type":"User","site_admin":false},"body":"https://github.com/metasfresh/metasfresh/issues/478","created_at":"2018-12-14T14:16:53Z","updated_at":"2018-12-20T08:35:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"36a96596d982571e7ec27be0150a143caa885b3c","assignee":{"login":"teosarca","id":1244701,"node_id":"MDQ6VXNlcjEyNDQ3MDE=","avatar_url":"https://avatars2.githubusercontent.com/u/1244701?v=4","gravatar_id":"","url":"https://api.github.com/users/teosarca","html_url":"https://github.com/teosarca","followers_url":"https://api.github.com/users/teosarca/followers","following_url":"https://api.github.com/users/teosarca/following{/other_user}","gists_url":"https://api.github.com/users/teosarca/gists{/gist_id}","starred_url":"https://api.github.com/users/teosarca/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/teosarca/subscriptions","organizations_url":"https://api.github.com/users/teosarca/orgs","repos_url":"https://api.github.com/users/teosarca/repos","events_url":"https://api.github.com/users/teosarca/events{/privacy}","received_events_url":"https://api.github.com/users/teosarca/received_events","type":"User","site_admin":false},"assignees":[{"login":"teosarca","id":1244701,"node_id":"MDQ6VXNlcjEyNDQ3MDE=","avatar_url":"https://avatars2.githubusercontent.com/u/1244701?v=4","gravatar_id":"","url":"https://api.github.com/users/teosarca","html_url":"https://github.com/teosarca","followers_url":"https://api.github.com/users/teosarca/followers","following_url":"https://api.github.com/users/teosarca/following{/other_user}","gists_url":"https://api.github.com/users/teosarca/gists{/gist_id}","starred_url":"https://api.github.com/users/teosarca/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/teosarca/subscriptions","organizations_url":"https://api.github.com/users/teosarca/orgs","repos_url":"https://api.github.com/users/teosarca/repos","events_url":"https://api.github.com/users/teosarca/events{/privacy}","received_events_url":"https://api.github.com/users/teosarca/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/metasfresh/metasfresh/pulls/4836/commits","review_comments_url":"https://api.github.com/repos/metasfresh/metasfresh/pulls/4836/comments","review_comment_url":"https://api.github.com/repos/metasfresh/metasfresh/pulls/comments{/number}","comments_url":"https://api.github.com/repos/metasfresh/metasfresh/issues/4836/comments","statuses_url":"https://api.github.com/repos/metasfresh/metasfresh/statuses/1690cd7216f4a6b4e6018f7d30ed66df9dbfedef","head":{"label":"metasfresh:gh478","ref":"gh478","sha":"1690cd7216f4a6b4e6018f7d30ed66df9dbfedef","user":{"login":"metasfresh","id":13364239,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEzMzY0MjM5","avatar_url":"https://avatars3.githubusercontent.com/u/13364239?v=4","gravatar_id":"","url":"https://api.github.com/users/metasfresh","html_url":"https://github.com/metasfresh","followers_url":"https://api.github.com/users/metasfresh/followers","following_url":"https://api.github.com/users/metasfresh/following{/other_user}","gists_url":"https://api.github.com/users/metasfresh/gists{/gist_id}","starred_url":"https://api.github.com/users/metasfresh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/metasfresh/subscriptions","organizations_url":"https://api.github.com/users/metasfresh/orgs","repos_url":"https://api.github.com/users/metasfresh/repos","events_url":"https://api.github.com/users/metasfresh/events{/privacy}","received_events_url":"https://api.github.com/users/metasfresh/received_events","type":"Organization","site_admin":false},"repo":{"id":43760104,"node_id":"MDEwOlJlcG9zaXRvcnk0Mzc2MDEwNA==","name":"metasfresh","full_name":"metasfresh/metasfresh","private":false,"owner":{"login":"metasfresh","id":13364239,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEzMzY0MjM5","avatar_url":"https://avatars3.githubusercontent.com/u/13364239?v=4","gravatar_id":"","url":"https://api.github.com/users/metasfresh","html_url":"https://github.com/metasfresh","followers_url":"https://api.github.com/users/metasfresh/followers","following_url":"https://api.github.com/users/metasfresh/following{/other_user}","gists_url":"https://api.github.com/users/metasfresh/gists{/gist_id}","starred_url":"https://api.github.com/users/metasfresh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/metasfresh/subscriptions","organizations_url":"https://api.github.com/users/metasfresh/orgs","repos_url":"https://api.github.com/users/metasfresh/repos","events_url":"https://api.github.com/users/metasfresh/events{/privacy}","received_events_url":"https://api.github.com/users/metasfresh/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/metasfresh/metasfresh","description":"Fast, Flexible & Free ERP for your Business Growth.","fork":false,"url":"https://api.github.com/repos/metasfresh/metasfresh","forks_url":"https://api.github.com/repos/metasfresh/metasfresh/forks","keys_url":"https://api.github.com/repos/metasfresh/metasfresh/keys{/key_id}","collaborators_url":"https://api.github.com/repos/metasfresh/metasfresh/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/metasfresh/metasfresh/teams","hooks_url":"https://api.github.com/repos/metasfresh/metasfresh/hooks","issue_events_url":"https://api.github.com/repos/metasfresh/metasfresh/issues/events{/number}","events_url":"https://api.github.com/repos/metasfresh/metasfresh/events","assignees_url":"https://api.github.com/repos/metasfresh/metasfresh/assignees{/user}","branches_url":"https://api.github.com/repos/metasfresh/metasfresh/branches{/branch}","tags_url":"https://api.github.com/repos/metasfresh/metasfresh/tags","blobs_url":"https://api.github.com/repos/metasfresh/metasfresh/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/metasfresh/metasfresh/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/metasfresh/metasfresh/git/refs{/sha}","trees_url":"https://api.github.com/repos/metasfresh/metasfresh/git/trees{/sha}","statuses_url":"https://api.github.com/repos/metasfresh/metasfresh/statuses/{sha}","languages_url":"https://api.github.com/repos/metasfresh/metasfresh/languages","stargazers_url":"https://api.github.com/repos/metasfresh/metasfresh/stargazers","contributors_url":"https://api.github.com/repos/metasfresh/metasfresh/contributors","subscribers_url":"https://api.github.com/repos/metasfresh/metasfresh/subscribers","subscription_url":"https://api.github.com/repos/metasfresh/metasfresh/subscription","commits_url":"https://api.github.com/repos/metasfresh/metasfresh/commits{/sha}","git_commits_url":"https://api.github.com/repos/metasfresh/metasfresh/git/commits{/sha}","comments_url":"https://api.github.com/repos/metasfresh/metasfresh/comments{/number}","issue_comment_url":"https://api.github.com/repos/metasfresh/metasfresh/issues/comments{/number}","contents_url":"https://api.github.com/repos/metasfresh/metasfresh/contents/{+path}","compare_url":"https://api.github.com/repos/metasfresh/metasfresh/compare/{base}...{head}","merges_url":"https://api.github.com/repos/metasfresh/metasfresh/merges","archive_url":"https://api.github.com/repos/metasfresh/metasfresh/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/metasfresh/metasfresh/downloads","issues_url":"https://api.github.com/repos/metasfresh/metasfresh/issues{/number}","pulls_url":"https://api.github.com/repos/metasfresh/metasfresh/pulls{/number}","milestones_url":"https://api.github.com/repos/metasfresh/metasfresh/milestones{/number}","notifications_url":"https://api.github.com/repos/metasfresh/metasfresh/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/metasfresh/metasfresh/labels{/name}","releases_url":"https://api.github.com/repos/metasfresh/metasfresh/releases{/id}","deployments_url":"https://api.github.com/repos/metasfresh/metasfresh/deployments","created_at":"2015-10-06T15:38:11Z","updated_at":"2018-12-19T14:56:01Z","pushed_at":"2018-12-20T08:20:37Z","git_url":"git://github.com/metasfresh/metasfresh.git","ssh_url":"git@github.com:metasfresh/metasfresh.git","clone_url":"https://github.com/metasfresh/metasfresh.git","svn_url":"https://github.com/metasfresh/metasfresh","homepage":"http://metasfresh.com/en","size":94505,"stargazers_count":309,"watchers_count":309,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":131,"mirror_url":null,"archived":false,"open_issues_count":942,"license":{"key":"gpl-2.0","name":"GNU General Public License v2.0","spdx_id":"GPL-2.0","url":"https://api.github.com/licenses/gpl-2.0","node_id":"MDc6TGljZW5zZTg="},"forks":131,"open_issues":942,"watchers":309,"default_branch":"master"}},"base":{"label":"metasfresh:master","ref":"master","sha":"28a847af0f9014100b80b2976bfaf8a3acd7f3c6","user":{"login":"metasfresh","id":13364239,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEzMzY0MjM5","avatar_url":"https://avatars3.githubusercontent.com/u/13364239?v=4","gravatar_id":"","url":"https://api.github.com/users/metasfresh","html_url":"https://github.com/metasfresh","followers_url":"https://api.github.com/users/metasfresh/followers","following_url":"https://api.github.com/users/metasfresh/following{/other_user}","gists_url":"https://api.github.com/users/metasfresh/gists{/gist_id}","starred_url":"https://api.github.com/users/metasfresh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/metasfresh/subscriptions","organizations_url":"https://api.github.com/users/metasfresh/orgs","repos_url":"https://api.github.com/users/metasfresh/repos","events_url":"https://api.github.com/users/metasfresh/events{/privacy}","received_events_url":"https://api.github.com/users/metasfresh/received_events","type":"Organization","site_admin":false},"repo":{"id":43760104,"node_id":"MDEwOlJlcG9zaXRvcnk0Mzc2MDEwNA==","name":"metasfresh","full_name":"metasfresh/metasfresh","private":false,"owner":{"login":"metasfresh","id":13364239,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEzMzY0MjM5","avatar_url":"https://avatars3.githubusercontent.com/u/13364239?v=4","gravatar_id":"","url":"https://api.github.com/users/metasfresh","html_url":"https://github.com/metasfresh","followers_url":"https://api.github.com/users/metasfresh/followers","following_url":"https://api.github.com/users/metasfresh/following{/other_user}","gists_url":"https://api.github.com/users/metasfresh/gists{/gist_id}","starred_url":"https://api.github.com/users/metasfresh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/metasfresh/subscriptions","organizations_url":"https://api.github.com/users/metasfresh/orgs","repos_url":"https://api.github.com/users/metasfresh/repos","events_url":"https://api.github.com/users/metasfresh/events{/privacy}","received_events_url":"https://api.github.com/users/metasfresh/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/metasfresh/metasfresh","description":"Fast, Flexible & Free ERP for your Business Growth.","fork":false,"url":"https://api.github.com/repos/metasfresh/metasfresh","forks_url":"https://api.github.com/repos/metasfresh/metasfresh/forks","keys_url":"https://api.github.com/repos/metasfresh/metasfresh/keys{/key_id}","collaborators_url":"https://api.github.com/repos/metasfresh/metasfresh/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/metasfresh/metasfresh/teams","hooks_url":"https://api.github.com/repos/metasfresh/metasfresh/hooks","issue_events_url":"https://api.github.com/repos/metasfresh/metasfresh/issues/events{/number}","events_url":"https://api.github.com/repos/metasfresh/metasfresh/events","assignees_url":"https://api.github.com/repos/metasfresh/metasfresh/assignees{/user}","branches_url":"https://api.github.com/repos/metasfresh/metasfresh/branches{/branch}","tags_url":"https://api.github.com/repos/metasfresh/metasfresh/tags","blobs_url":"https://api.github.com/repos/metasfresh/metasfresh/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/metasfresh/metasfresh/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/metasfresh/metasfresh/git/refs{/sha}","trees_url":"https://api.github.com/repos/metasfresh/metasfresh/git/trees{/sha}","statuses_url":"https://api.github.com/repos/metasfresh/metasfresh/statuses/{sha}","languages_url":"https://api.github.com/repos/metasfresh/metasfresh/languages","stargazers_url":"https://api.github.com/repos/metasfresh/metasfresh/stargazers","contributors_url":"https://api.github.com/repos/metasfresh/metasfresh/contributors","subscribers_url":"https://api.github.com/repos/metasfresh/metasfresh/subscribers","subscription_url":"https://api.github.com/repos/metasfresh/metasfresh/subscription","commits_url":"https://api.github.com/repos/metasfresh/metasfresh/commits{/sha}","git_commits_url":"https://api.github.com/repos/metasfresh/metasfresh/git/commits{/sha}","comments_url":"https://api.github.com/repos/metasfresh/metasfresh/comments{/number}","issue_comment_url":"https://api.github.com/repos/metasfresh/metasfresh/issues/comments{/number}","contents_url":"https://api.github.com/repos/metasfresh/metasfresh/contents/{+path}","compare_url":"https://api.github.com/repos/metasfresh/metasfresh/compare/{base}...{head}","merges_url":"https://api.github.com/repos/metasfresh/metasfresh/merges","archive_url":"https://api.github.com/repos/metasfresh/metasfresh/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/metasfresh/metasfresh/downloads","issues_url":"https://api.github.com/repos/metasfresh/metasfresh/issues{/number}","pulls_url":"https://api.github.com/repos/metasfresh/metasfresh/pulls{/number}","milestones_url":"https://api.github.com/repos/metasfresh/metasfresh/milestones{/number}","notifications_url":"https://api.github.com/repos/metasfresh/metasfresh/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/metasfresh/metasfresh/labels{/name}","releases_url":"https://api.github.com/repos/metasfresh/metasfresh/releases{/id}","deployments_url":"https://api.github.com/repos/metasfresh/metasfresh/deployments","created_at":"2015-10-06T15:38:11Z","updated_at":"2018-12-19T14:56:01Z","pushed_at":"2018-12-20T08:20:37Z","git_url":"git://github.com/metasfresh/metasfresh.git","ssh_url":"git@github.com:metasfresh/metasfresh.git","clone_url":"https://github.com/metasfresh/metasfresh.git","svn_url":"https://github.com/metasfresh/metasfresh","homepage":"http://metasfresh.com/en","size":94505,"stargazers_count":309,"watchers_count":309,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":131,"mirror_url":null,"archived":false,"open_issues_count":942,"license":{"key":"gpl-2.0","name":"GNU General Public License v2.0","spdx_id":"GPL-2.0","url":"https://api.github.com/licenses/gpl-2.0","node_id":"MDc6TGljZW5zZTg="},"forks":131,"open_issues":942,"watchers":309,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/metasfresh/metasfresh/pulls/4836"},"html":{"href":"https://github.com/metasfresh/metasfresh/pull/4836"},"issue":{"href":"https://api.github.com/repos/metasfresh/metasfresh/issues/4836"},"comments":{"href":"https://api.github.com/repos/metasfresh/metasfresh/issues/4836/comments"},"review_comments":{"href":"https://api.github.com/repos/metasfresh/metasfresh/pulls/4836/comments"},"review_comment":{"href":"https://api.github.com/repos/metasfresh/metasfresh/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/metasfresh/metasfresh/pulls/4836/commits"},"statuses":{"href":"https://api.github.com/repos/metasfresh/metasfresh/statuses/1690cd7216f4a6b4e6018f7d30ed66df9dbfedef"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"codacy-bot"}}