use of org.apache.ofbiz.entity.condition.EntityCondition in project ofbiz-framework by apache.
the class PeriodServices method findLastClosedDate.
/*
* find the date of the last closed CustomTimePeriod, or, if none available, the
* earliest date available of any CustomTimePeriod
*/
public static Map<String, Object> findLastClosedDate(DispatchContext dctx, Map<String, ?> context) {
Delegator delegator = dctx.getDelegator();
// input parameters
String organizationPartyId = (String) context.get("organizationPartyId");
String periodTypeId = (String) context.get("periodTypeId");
Timestamp findDate = (Timestamp) context.get("findDate");
Locale locale = (Locale) context.get("locale");
// default findDate to now
if (findDate == null) {
findDate = UtilDateTime.nowTimestamp();
}
// return parameters
Timestamp lastClosedDate = null;
GenericValue lastClosedTimePeriod = null;
Map<String, Object> result = ServiceUtil.returnSuccess();
try {
// try to get the ending date of the most recent accounting time period before
// findDate which has been closed
List<EntityCondition> findClosedConditions = UtilMisc.toList(EntityCondition.makeConditionMap("organizationPartyId", organizationPartyId), EntityCondition.makeCondition("thruDate", EntityOperator.LESS_THAN_EQUAL_TO, findDate), EntityCondition.makeConditionMap("isClosed", "Y"));
if (UtilValidate.isNotEmpty(periodTypeId)) {
// if a periodTypeId was supplied, use it
findClosedConditions.add(EntityCondition.makeConditionMap("periodTypeId", periodTypeId));
}
GenericValue closedTimePeriod = EntityQuery.use(delegator).from("CustomTimePeriod").select("customTimePeriodId", "periodTypeId", "isClosed", "fromDate", "thruDate").where(findClosedConditions).orderBy("thruDate DESC").queryFirst();
if (UtilValidate.isNotEmpty(closedTimePeriod) && UtilValidate.isNotEmpty(closedTimePeriod.get("thruDate"))) {
lastClosedTimePeriod = closedTimePeriod;
lastClosedDate = lastClosedTimePeriod.getTimestamp("thruDate");
} else {
// uh oh, no time periods have been closed? in that case, just find the earliest
// beginning of a time period for this organization and optionally, for this period type
Map<String, String> findParams = UtilMisc.toMap("organizationPartyId", organizationPartyId);
if (UtilValidate.isNotEmpty(periodTypeId)) {
findParams.put("periodTypeId", periodTypeId);
}
GenericValue timePeriod = EntityQuery.use(delegator).from("CustomTimePeriod").where(findParams).orderBy("fromDate ASC").queryFirst();
if (timePeriod != null && UtilValidate.isNotEmpty(timePeriod.get("fromDate"))) {
lastClosedDate = timePeriod.getTimestamp("fromDate");
} else {
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingPeriodCannotGet", locale));
}
}
// ok if this is null - no time periods have been closed
result.put("lastClosedTimePeriod", lastClosedTimePeriod);
// should have a value - not null
result.put("lastClosedDate", lastClosedDate);
return result;
} catch (GenericEntityException ex) {
return (ServiceUtil.returnError(ex.getMessage()));
}
}
use of org.apache.ofbiz.entity.condition.EntityCondition in project ofbiz-framework by apache.
the class TaxAuthorityServices method getTaxAdjustments.
private static List<GenericValue> getTaxAdjustments(Delegator delegator, GenericValue product, GenericValue productStore, String payToPartyId, String billToPartyId, Set<GenericValue> taxAuthoritySet, BigDecimal itemPrice, BigDecimal itemQuantity, BigDecimal itemAmount, BigDecimal shippingAmount, BigDecimal orderPromotionsAmount) {
Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
List<GenericValue> adjustments = new LinkedList<>();
if (payToPartyId == null) {
if (productStore != null) {
payToPartyId = productStore.getString("payToPartyId");
}
}
// store expr
EntityCondition storeCond = null;
if (productStore != null) {
storeCond = EntityCondition.makeCondition(EntityCondition.makeCondition("productStoreId", EntityOperator.EQUALS, productStore.get("productStoreId")), EntityOperator.OR, EntityCondition.makeCondition("productStoreId", EntityOperator.EQUALS, null));
} else {
storeCond = EntityCondition.makeCondition("productStoreId", EntityOperator.EQUALS, null);
}
// build the TaxAuthority expressions (taxAuthGeoId, taxAuthPartyId)
List<EntityCondition> taxAuthCondOrList = new LinkedList<>();
// start with the _NA_ TaxAuthority...
taxAuthCondOrList.add(EntityCondition.makeCondition(EntityCondition.makeCondition("taxAuthPartyId", EntityOperator.EQUALS, "_NA_"), EntityOperator.AND, EntityCondition.makeCondition("taxAuthGeoId", EntityOperator.EQUALS, "_NA_")));
for (GenericValue taxAuthority : taxAuthoritySet) {
EntityCondition taxAuthCond = EntityCondition.makeCondition(EntityCondition.makeCondition("taxAuthPartyId", EntityOperator.EQUALS, taxAuthority.getString("taxAuthPartyId")), EntityOperator.AND, EntityCondition.makeCondition("taxAuthGeoId", EntityOperator.EQUALS, taxAuthority.getString("taxAuthGeoId")));
taxAuthCondOrList.add(taxAuthCond);
}
EntityCondition taxAuthoritiesCond = EntityCondition.makeCondition(taxAuthCondOrList, EntityOperator.OR);
try {
EntityCondition productCategoryCond;
productCategoryCond = setProductCategoryCond(delegator, product);
// https://issues.apache.org/jira/browse/OFBIZ-4160 for a better one
if (product == null && shippingAmount != null) {
EntityCondition taxShippingCond = EntityCondition.makeCondition(EntityCondition.makeCondition("taxShipping", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("taxShipping", EntityOperator.EQUALS, "Y"));
productCategoryCond = EntityCondition.makeCondition(productCategoryCond, EntityOperator.OR, taxShippingCond);
}
if (product == null && orderPromotionsAmount != null) {
EntityCondition taxOrderPromotionsCond = EntityCondition.makeCondition(EntityCondition.makeCondition("taxPromotions", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("taxPromotions", EntityOperator.EQUALS, "Y"));
productCategoryCond = EntityCondition.makeCondition(productCategoryCond, EntityOperator.OR, taxOrderPromotionsCond);
}
// build the main condition clause
List<EntityCondition> mainExprs = UtilMisc.toList(storeCond, taxAuthoritiesCond, productCategoryCond);
mainExprs.add(EntityCondition.makeCondition(EntityCondition.makeCondition("minItemPrice", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("minItemPrice", EntityOperator.LESS_THAN_EQUAL_TO, itemPrice)));
mainExprs.add(EntityCondition.makeCondition(EntityCondition.makeCondition("minPurchase", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("minPurchase", EntityOperator.LESS_THAN_EQUAL_TO, itemAmount)));
EntityCondition mainCondition = EntityCondition.makeCondition(mainExprs, EntityOperator.AND);
// finally ready... do the rate query
List<GenericValue> lookupList = EntityQuery.use(delegator).from("TaxAuthorityRateProduct").where(mainCondition).orderBy("minItemPrice", "minPurchase", "fromDate").filterByDate().queryList();
if (lookupList.size() == 0) {
Debug.logWarning("In TaxAuthority Product Rate no records were found for condition:" + mainCondition.toString(), module);
return adjustments;
}
// find the right entry(s) based on purchase amount
for (GenericValue taxAuthorityRateProduct : lookupList) {
BigDecimal taxRate = taxAuthorityRateProduct.get("taxPercentage") != null ? taxAuthorityRateProduct.getBigDecimal("taxPercentage") : ZERO_BASE;
BigDecimal taxable = ZERO_BASE;
if (product != null && (product.get("taxable") == null || (product.get("taxable") != null && product.getBoolean("taxable").booleanValue()))) {
taxable = taxable.add(itemAmount);
}
if (shippingAmount != null && (taxAuthorityRateProduct.get("taxShipping") == null || (taxAuthorityRateProduct.get("taxShipping") != null && taxAuthorityRateProduct.getBoolean("taxShipping").booleanValue()))) {
taxable = taxable.add(shippingAmount);
}
if (orderPromotionsAmount != null && (taxAuthorityRateProduct.get("taxPromotions") == null || (taxAuthorityRateProduct.get("taxPromotions") != null && taxAuthorityRateProduct.getBoolean("taxPromotions").booleanValue()))) {
taxable = taxable.add(orderPromotionsAmount);
}
if (taxable.compareTo(BigDecimal.ZERO) == 0) {
// Y/true, and there is no shipping and such
continue;
}
// taxRate is in percentage, so needs to be divided by 100
BigDecimal taxAmount = (taxable.multiply(taxRate)).divide(PERCENT_SCALE, salestaxCalcDecimals, salestaxRounding);
String taxAuthGeoId = taxAuthorityRateProduct.getString("taxAuthGeoId");
String taxAuthPartyId = taxAuthorityRateProduct.getString("taxAuthPartyId");
// get glAccountId from TaxAuthorityGlAccount entity using the payToPartyId as
// the organizationPartyId
GenericValue taxAuthorityGlAccount = EntityQuery.use(delegator).from("TaxAuthorityGlAccount").where("taxAuthPartyId", taxAuthPartyId, "taxAuthGeoId", taxAuthGeoId, "organizationPartyId", payToPartyId).queryOne();
String taxAuthGlAccountId = null;
if (taxAuthorityGlAccount != null) {
taxAuthGlAccountId = taxAuthorityGlAccount.getString("glAccountId");
} else {
// TODO: what to do if no TaxAuthorityGlAccount found? Use some default, or is
// that done elsewhere later on?
}
GenericValue productPrice = null;
if (product != null && taxAuthPartyId != null && taxAuthGeoId != null) {
// find a ProductPrice for the productId and taxAuth* values, and see if it has
// a priceWithTax value
productPrice = EntityQuery.use(delegator).from("ProductPrice").where("productId", product.get("productId"), "taxAuthPartyId", taxAuthPartyId, "taxAuthGeoId", taxAuthGeoId, "productPricePurposeId", "PURCHASE").orderBy("-fromDate").filterByDate().queryFirst();
if (productPrice == null) {
GenericValue virtualProduct = ProductWorker.getParentProduct(product.getString("productId"), delegator);
if (virtualProduct != null) {
productPrice = EntityQuery.use(delegator).from("ProductPrice").where("productId", virtualProduct.get("productId"), "taxAuthPartyId", taxAuthPartyId, "taxAuthGeoId", taxAuthGeoId, "productPricePurposeId", "PURCHASE").orderBy("-fromDate").filterByDate().queryFirst();
}
}
}
GenericValue taxAdjValue = delegator.makeValue("OrderAdjustment");
BigDecimal discountedSalesTax = BigDecimal.ZERO;
taxAdjValue.set("orderAdjustmentTypeId", "SALES_TAX");
if (productPrice != null && "Y".equals(productPrice.getString("taxInPrice")) && itemQuantity != BigDecimal.ZERO) {
// For example product price is 43 with 20% VAT(means product actual price is
// 35.83).
// itemPrice = 43;
// itemQuantity = 3;
// taxAmountIncludedInFullPrice = (43-(43/(1+(20/100))))*3 = 21.51
taxAdjValue.set("orderAdjustmentTypeId", "VAT_TAX");
BigDecimal taxAmountIncludedInFullPrice = itemPrice.subtract(itemPrice.divide(BigDecimal.ONE.add(taxRate.divide(PERCENT_SCALE, 4, RoundingMode.HALF_UP)), 2, RoundingMode.HALF_UP)).multiply(itemQuantity);
// If 1 quantity has 50% discount then itemAmount = 107.5 otherwise 129 (In case
// of no discount)
// Net price for each item
// netItemPrice = itemAmount / quantity = 107.5 / 3 = 35.833333333
BigDecimal netItemPrice = itemAmount.divide(itemQuantity, RoundingMode.HALF_UP);
// Calculate tax on the discounted price, be sure to round to 2 decimal places
// before multiplying by quantity
// netTax = (netItemPrice - netItemPrice / (1 + (taxRate/100))) * quantity
// netTax = (35.833333333-(35.833333333/(1+(20/100))))*3 = 17.92
BigDecimal netTax = netItemPrice.subtract(netItemPrice.divide(BigDecimal.ONE.add(taxRate.divide(PERCENT_SCALE, 4, RoundingMode.HALF_UP)), 2, RoundingMode.HALF_UP)).multiply(itemQuantity);
// Subtract net tax from base tax (taxAmountIncludedFullPrice) to get the
// negative promotion tax adjustment amount
// discountedSalesTax = 17.92 - 21.51 = −3.59 (If no discounted item quantity
// then discountedSalesTax will be ZERO)
discountedSalesTax = netTax.subtract(taxAmountIncludedInFullPrice);
taxAdjValue.set("amountAlreadyIncluded", taxAmountIncludedInFullPrice);
taxAdjValue.set("amount", BigDecimal.ZERO);
} else {
taxAdjValue.set("amount", taxAmount);
}
taxAdjValue.set("sourcePercentage", taxRate);
taxAdjValue.set("taxAuthorityRateSeqId", taxAuthorityRateProduct.getString("taxAuthorityRateSeqId"));
// the primary Geo should be the main jurisdiction that the tax is for, and the
// secondary would just be to define a parent or wrapping jurisdiction of the
// primary
taxAdjValue.set("primaryGeoId", taxAuthGeoId);
taxAdjValue.set("comments", taxAuthorityRateProduct.getString("description"));
if (taxAuthPartyId != null) {
taxAdjValue.set("taxAuthPartyId", taxAuthPartyId);
}
if (taxAuthGlAccountId != null) {
taxAdjValue.set("overrideGlAccountId", taxAuthGlAccountId);
}
if (taxAuthGeoId != null) {
taxAdjValue.set("taxAuthGeoId", taxAuthGeoId);
}
// exempt in the primary (most-local) jurisdiction
if (UtilValidate.isNotEmpty(billToPartyId) && UtilValidate.isNotEmpty(taxAuthGeoId)) {
// see if partyId is a member of any groups, if so honor their tax exemptions
// look for PartyRelationship with partyRelationshipTypeId=GROUP_ROLLUP, the
// partyIdTo is the group member, so the partyIdFrom is the groupPartyId
Set<String> billToPartyIdSet = new HashSet<>();
billToPartyIdSet.add(billToPartyId);
List<GenericValue> partyRelationshipList = EntityQuery.use(delegator).from("PartyRelationship").where("partyIdTo", billToPartyId, "partyRelationshipTypeId", "GROUP_ROLLUP").cache().filterByDate().queryList();
for (GenericValue partyRelationship : partyRelationshipList) {
billToPartyIdSet.add(partyRelationship.getString("partyIdFrom"));
}
handlePartyTaxExempt(taxAdjValue, billToPartyIdSet, taxAuthGeoId, taxAuthPartyId, taxAmount, nowTimestamp, delegator);
} else {
Debug.logInfo("NOTE: A tax calculation was done without a billToPartyId or taxAuthGeoId, so no tax exemptions or tax IDs considered; billToPartyId=[" + billToPartyId + "] taxAuthGeoId=[" + taxAuthGeoId + "]", module);
}
if (discountedSalesTax.compareTo(BigDecimal.ZERO) < 0) {
GenericValue taxAdjValueNegative = delegator.makeValue("OrderAdjustment");
taxAdjValueNegative.setFields(taxAdjValue);
taxAdjValueNegative.set("amountAlreadyIncluded", discountedSalesTax);
adjustments.add(taxAdjValueNegative);
}
adjustments.add(taxAdjValue);
if (productPrice != null && itemQuantity != null && productPrice.getBigDecimal("priceWithTax") != null && !"Y".equals(productPrice.getString("taxInPrice"))) {
BigDecimal priceWithTax = productPrice.getBigDecimal("priceWithTax");
BigDecimal price = productPrice.getBigDecimal("price");
BigDecimal baseSubtotal = price.multiply(itemQuantity);
BigDecimal baseTaxAmount = (baseSubtotal.multiply(taxRate)).divide(PERCENT_SCALE, salestaxCalcDecimals, salestaxRounding);
// tax is not already in price so we want to add it in, but this is a VAT
// situation so adjust to make it as accurate as possible
// for VAT taxes if the calculated total item price plus calculated taxes is
// different from what would be
// expected based on the original entered price with taxes (if the price was
// entered this way), then create
// an adjustment that corrects for the difference, and this correction will be
// effectively subtracted from the
// price and not from the tax (the tax is meant to be calculated based on Tax
// Authority rules and so should
// not be shorted)
// TODO (don't think this is needed, but just to keep it in mind): get this to
// work with multiple VAT tax authorities instead of just one (right now will
// get incorrect totals if there are multiple taxes included in the price)
// TODO add constraint to ProductPrice lookup by any productStoreGroupId
// associated with the current productStore
BigDecimal enteredTotalPriceWithTax = priceWithTax.multiply(itemQuantity);
BigDecimal calcedTotalPriceWithTax = (baseSubtotal).add(baseTaxAmount);
if (!enteredTotalPriceWithTax.equals(calcedTotalPriceWithTax)) {
// if the calculated amount is higher than the entered amount we want the value
// to be negative
// to get it down to match the entered amount
// so, subtract the calculated amount from the entered amount (ie: correction =
// entered - calculated)
BigDecimal correctionAmount = enteredTotalPriceWithTax.subtract(calcedTotalPriceWithTax);
GenericValue correctionAdjValue = delegator.makeValue("OrderAdjustment");
correctionAdjValue.set("taxAuthorityRateSeqId", taxAuthorityRateProduct.getString("taxAuthorityRateSeqId"));
correctionAdjValue.set("amount", correctionAmount);
// don't set this, causes a doubling of the tax rate because calling code adds
// up all tax rates: correctionAdjValue.set("sourcePercentage", taxRate);
correctionAdjValue.set("orderAdjustmentTypeId", "VAT_PRICE_CORRECT");
// the primary Geo should be the main jurisdiction that the tax is for, and the
// secondary would just be to define a parent or wrapping jurisdiction of the
// primary
correctionAdjValue.set("primaryGeoId", taxAuthGeoId);
correctionAdjValue.set("comments", taxAuthorityRateProduct.getString("description"));
if (taxAuthPartyId != null) {
correctionAdjValue.set("taxAuthPartyId", taxAuthPartyId);
}
if (taxAuthGlAccountId != null) {
correctionAdjValue.set("overrideGlAccountId", taxAuthGlAccountId);
}
if (taxAuthGeoId != null) {
correctionAdjValue.set("taxAuthGeoId", taxAuthGeoId);
}
adjustments.add(correctionAdjValue);
}
}
}
} catch (GenericEntityException e) {
Debug.logError(e, "Problems looking up tax rates", module);
return new LinkedList<>();
}
return adjustments;
}
use of org.apache.ofbiz.entity.condition.EntityCondition in project ofbiz-framework by apache.
the class TaxAuthorityServices method setProductCategoryCond.
/**
* Private helper method which determines, based on the state of the product,
* how the ProdCondition should be set for the main condition.
*
* @param delegator
* @param product
* which may be null
* @return non-null Condition
* @throws GenericEntityException
*/
private static EntityCondition setProductCategoryCond(Delegator delegator, GenericValue product) throws GenericEntityException {
if (product == null) {
return EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS, null);
}
// find the tax categories associated with the product and filter by
// those, with an IN clause or some such
// if this product is variant, find the virtual product id and consider
// also the categories of the virtual
// question: get all categories, or just a special type? for now let's
// do all categories...
String virtualProductId = null;
if ("Y".equals(product.getString("isVariant"))) {
virtualProductId = ProductWorker.getVariantVirtualId(product);
}
Set<String> productCategoryIdSet = new HashSet<>();
EntityCondition productIdCond = null;
if (virtualProductId != null) {
productIdCond = EntityCondition.makeCondition(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, product.getString("productId")), EntityOperator.OR, EntityCondition.makeCondition("productId", EntityOperator.EQUALS, virtualProductId));
} else {
productIdCond = EntityCondition.makeCondition("productId", EntityOperator.EQUALS, product.getString("productId"));
}
List<GenericValue> pcmList = EntityQuery.use(delegator).select("productCategoryId", "fromDate", "thruDate").from("ProductCategoryMember").where(productIdCond).cache().filterByDate().queryList();
for (GenericValue pcm : pcmList) {
productCategoryIdSet.add(pcm.getString("productCategoryId"));
}
if (productCategoryIdSet.size() == 0) {
return EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS, null);
}
return EntityCondition.makeCondition(EntityCondition.makeCondition("productCategoryId", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("productCategoryId", EntityOperator.IN, productCategoryIdSet));
}
use of org.apache.ofbiz.entity.condition.EntityCondition in project ofbiz-framework by apache.
the class UtilAccounting method getGlExchangeRateOfPurchaseInvoice.
public static BigDecimal getGlExchangeRateOfPurchaseInvoice(GenericValue paymentApplication) throws GenericEntityException {
BigDecimal exchangeRate = BigDecimal.ONE;
Delegator delegator = paymentApplication.getDelegator();
List<EntityExpr> andConditions = UtilMisc.toList(EntityCondition.makeCondition("glAccountTypeId", "ACCOUNTS_PAYABLE"), EntityCondition.makeCondition("debitCreditFlag", "C"), EntityCondition.makeCondition("acctgTransTypeId", "PURCHASE_INVOICE"), EntityCondition.makeCondition("invoiceId", paymentApplication.getString("invoiceId")));
EntityCondition whereCondition = EntityCondition.makeCondition(andConditions, EntityJoinOperator.AND);
GenericValue amounts = EntityQuery.use(delegator).select("origAmount", "amount").from("AcctgTransAndEntries").where(whereCondition).queryFirst();
if (amounts == null) {
return exchangeRate;
}
BigDecimal origAmount = amounts.getBigDecimal("origAmount");
BigDecimal amount = amounts.getBigDecimal("amount");
if (origAmount != null && amount != null && BigDecimal.ZERO.compareTo(origAmount) != 0 && BigDecimal.ZERO.compareTo(amount) != 0 && amount.compareTo(origAmount) != 0) {
exchangeRate = amount.divide(origAmount, UtilNumber.getBigDecimalScale("ledger.decimals"), UtilNumber.getRoundingMode("invoice.rounding"));
}
return exchangeRate;
}
use of org.apache.ofbiz.entity.condition.EntityCondition in project ofbiz-framework by apache.
the class UtilAccounting method getGlExchangeRateOfOutgoingPayment.
public static BigDecimal getGlExchangeRateOfOutgoingPayment(GenericValue paymentApplication) throws GenericEntityException {
BigDecimal exchangeRate = BigDecimal.ONE;
Delegator delegator = paymentApplication.getDelegator();
List<EntityExpr> andConditions = UtilMisc.toList(EntityCondition.makeCondition("glAccountTypeId", "CURRENT_ASSET"), EntityCondition.makeCondition("debitCreditFlag", "C"), EntityCondition.makeCondition("acctgTransTypeId", "OUTGOING_PAYMENT"), EntityCondition.makeCondition("paymentId", paymentApplication.getString("paymentId")));
EntityCondition whereCondition = EntityCondition.makeCondition(andConditions, EntityJoinOperator.AND);
GenericValue amounts = EntityQuery.use(delegator).select("origAmount", "amount").from("AcctgTransAndEntries").where(whereCondition).queryFirst();
if (amounts == null) {
return exchangeRate;
}
BigDecimal origAmount = amounts.getBigDecimal("origAmount");
BigDecimal amount = amounts.getBigDecimal("amount");
if (origAmount != null && amount != null && BigDecimal.ZERO.compareTo(origAmount) != 0 && BigDecimal.ZERO.compareTo(amount) != 0 && amount.compareTo(origAmount) != 0) {
exchangeRate = amount.divide(origAmount, UtilNumber.getBigDecimalScale("ledger.decimals"), UtilNumber.getRoundingMode("invoice.rounding"));
}
return exchangeRate;
}
Aggregations