Skip to content

Commit

Permalink
Initial contribution (openhab#14529)
Browse files Browse the repository at this point in the history
Signed-off-by: Jacob Laursen <[email protected]>
  • Loading branch information
jlaur authored and renescherer committed Mar 23, 2023
1 parent fbd37a8 commit f0b1e2a
Show file tree
Hide file tree
Showing 15 changed files with 660 additions and 0 deletions.
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@
/bundles/org.openhab.transform.regex/ @openhab/add-ons-maintainers
/bundles/org.openhab.transform.rollershutterposition/ @jsjames
/bundles/org.openhab.transform.scale/ @clinique
/bundles/org.openhab.transform.vat/ @jlaur
/bundles/org.openhab.transform.xpath/ @openhab/add-ons-maintainers
/bundles/org.openhab.transform.xslt/ @openhab/add-ons-maintainers
/bundles/org.openhab.voice.googlestt/ @GiviMAD
Expand Down
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2006,6 +2006,11 @@
<artifactId>org.openhab.transform.scale</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.vat</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.transform.xpath</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.transform.vat/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
This content is produced and maintained by the openHAB project.

* Project home: https://www.openhab.org

== Declared Project Licenses

This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.

== Source Code

https://github.com/openhab/openhab-addons
41 changes: 41 additions & 0 deletions bundles/org.openhab.transform.vat/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# VAT Transformation Service

The VAT Transformation Service adds VAT (Value-Added Tax) to a given input amount.
The input string must be either an ISO 3166 alpha-2 country code or a percentage, i.e. numerical format.

## Examples

### Display

```java
Number CurrentSpotPrice "Current Spot Price incl. VAT [VAT(12.5):%s]" <price>
```

### In a Rule

Add Danish VAT to price:

```java
var Number price = 499
logInfo("Price", "Price incl. VAT: " + transform("VAT", "DK", price.toString))
```

## Usage as a Profile

The functionality of this `TransformationService` can also be used in a `Profile` on an `ItemChannelLink`.
This is the most powerful usage since VAT will be added without providing any explicit country code, percentage or configuration.
To use this, an `.items` file can be configured as follows:

```java
Number CurrentSpotPrice "Current Spot Price" <price> { channel="<channelUID>" [profile="transform:VAT"] }
```

To override VAT percentage for configured system country:

```java
Number CurrentSpotPrice "Current Spot Price" <price> { channel="<channelUID>" [profile="transform:VAT", percentage="12.5"] }
```

If VAT is not known for the configured country or the provided percentage is invalid, the default is 0%, so the input value will be put into the transformation without any changes.

Please note: This profile is a one-way transformation, i.e. only values from a device towards the item are changed, the other direction is left untouched.
17 changes: 17 additions & 0 deletions bundles/org.openhab.transform.vat/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
<version>4.0.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.transform.vat</artifactId>

<name>openHAB Add-ons :: Bundles :: Transformation Service :: Value-Added Tax</name>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<features name="org.openhab.transform.vat-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>

<feature name="openhab-transformation-vat" description="Value-Added Tax Transformation" version="${project.version}">
<feature>openhab-runtime-base</feature>
<bundle start-level="75">mvn:org.openhab.addons.bundles/org.openhab.transform.vat/${project.version}</bundle>
</feature>
</features>
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.transform.vat.internal;

import java.util.Map;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.profiles.ProfileTypeUID;
import org.openhab.core.transform.TransformationService;

/**
* The {@link VATTransformationConstants} class defines constants
* used across the whole profile.
*
* @author Jacob Laursen - Initial contribution
*/
@NonNullByDefault
public class VATTransformationConstants {

public static final ProfileTypeUID PROFILE_TYPE_UID = new ProfileTypeUID(
TransformationService.TRANSFORM_PROFILE_SCOPE, "VAT");

public static final Map<String, String> RATES = Map.ofEntries(
// European Union countries
Map.entry("AT", "20"), // Austria
Map.entry("BE", "21"), // Belgium
Map.entry("BG", "20"), // Bulgaria
Map.entry("HR", "25"), // Croatia
Map.entry("CY", "19"), // Cyprus
Map.entry("CZ", "21"), // Czech Republic
Map.entry("DK", "25"), // Denmark
Map.entry("EE", "20"), // Estonia
Map.entry("FI", "24"), // Finland
Map.entry("FR", "20"), // France
Map.entry("DE", "19"), // Germany
Map.entry("GR", "24"), // Greece
Map.entry("HU", "27"), // Hungary
Map.entry("IE", "23"), // Ireland
Map.entry("IT", "22"), // Italy
Map.entry("LV", "21"), // Latvia
Map.entry("LT", "21"), // Lithuania
Map.entry("LU", "17"), // Luxembourg
Map.entry("MT", "18"), // Malta
Map.entry("NL", "21"), // Netherlands
Map.entry("PL", "23"), // Poland
Map.entry("PT", "23"), // Portugal
Map.entry("RO", "19"), // Romania
Map.entry("SK", "20"), // Slovakia
Map.entry("SI", "22"), // Slovenia
Map.entry("ES", "21"), // Spain
Map.entry("SE", "25"), // Sweden

// Non-European Union countries
Map.entry("AL", "20"), // Albania
Map.entry("DZ", "19"), // Algeria
Map.entry("AD", "4.5"), // Andorra
Map.entry("AO", "14"), // Angola
Map.entry("AG", "15"), // Antigua and Barbuda
Map.entry("AR", "21"), // Argentina
Map.entry("AM", "20"), // Armenia
Map.entry("AU", "10"), // Australia
Map.entry("AZ", "18"), // Azerbaijan
Map.entry("BS", "12"), // Bahamas
Map.entry("BH", "10"), // Bahrain
Map.entry("BD", "15"), // Bangladesh
Map.entry("BB", "17.5"), // Barbados
Map.entry("BY", "20"), // Belarus
Map.entry("BZ", "12.5"), // Belize
Map.entry("BJ", "18"), // Benin
Map.entry("BO", "13"), // Bolivia
Map.entry("BA", "17"), // Bosnia and Herzegovina
Map.entry("BW", "12"), // Botswana
Map.entry("BR", "20"), // Brazil
Map.entry("BF", "18"), // Burkina Faso
Map.entry("BI", "18"), // Burundi
Map.entry("KH", "10"), // Cambodia
Map.entry("CM", "19.25"), // Cameroon
Map.entry("CA", "5"), // Canada
Map.entry("CV", "15"), // Cape Verde
Map.entry("CF", "19"), // Central African Republic
Map.entry("TD", "18"), // Chad
Map.entry("CL", "19"), // Chile
Map.entry("CN", "13"), // China
Map.entry("CO", "19"), // Colombia
Map.entry("CR", "13"), // Costa Rica
Map.entry("CD", "16"), // Democratic Republic of the Congo
Map.entry("DM", "15"), // Dominica
Map.entry("DO", "18"), // Dominican Republic
Map.entry("EC", "12"), // Ecuador
Map.entry("EG", "14"), // Egypt
Map.entry("SV", "13"), // El Salvador
Map.entry("GQ", "15"), // Equatorial Guinea
Map.entry("ET", "15"), // Ethiopia
Map.entry("FO", "25"), // Faroe Islands
Map.entry("FJ", "15"), // Fiji
Map.entry("GA", "18"), // Gabon
Map.entry("GM", "15"), // Gambia
Map.entry("GE", "18"), // Georgia
Map.entry("GH", "15"), // Ghana
Map.entry("GD", "15"), // Grenada
Map.entry("GT", "12"), // Guatemala
Map.entry("GN", "18"), // Guinea
Map.entry("GW", "15"), // Guinea-Bissau
Map.entry("GY", "16"), // Guyana
Map.entry("HT", "10"), // Haiti
Map.entry("HN", "15"), // Honduras
Map.entry("IS", "24"), // Iceland
Map.entry("IN", "5.5"), // India
Map.entry("ID", "11"), // Indonesia
Map.entry("IR", "9"), // Iran
Map.entry("IM", "20"), // Isle of Man
Map.entry("IL", "17"), // Israel
Map.entry("CI", "18"), // Ivory Coast
Map.entry("JM", "12.5"), // Jamaica
Map.entry("JP", "10"), // Japan
Map.entry("JE", "5"), // Jersey
Map.entry("JO", "16"), // Jordan
Map.entry("KZ", "12"), // Kazakhstan
Map.entry("KE", "16"), // Kenya
Map.entry("KG", "20"), // Kyrgyzstan
Map.entry("LA", "10"), // Laos
Map.entry("LB", "11"), // Lebanon
Map.entry("LS", "14"), // Lesotho
Map.entry("LI", "7.7"), // Liechtenstein
Map.entry("MG", "20"), // Madagascar
Map.entry("MW", "16.5"), // Malawi
Map.entry("MY", "6"), // Malaysia
Map.entry("MV", "6"), // Maldives
Map.entry("ML", "18"), // Mali
Map.entry("MR", "14"), // Mauritania
Map.entry("MU", "15"), // Mauritius
Map.entry("MX", "16"), // Mexico
Map.entry("MD", "20"), // Moldova
Map.entry("MC", "19.6"), // Monaco
Map.entry("MN", "10"), // Mongolia
Map.entry("ME", "21"), // Montenegro
Map.entry("MA", "20"), // Morocco
Map.entry("MZ", "17"), // Mozambique
Map.entry("NA", "15"), // Namibia
Map.entry("NP", "13"), // Nepal
Map.entry("NZ", "15"), // New Zealand
Map.entry("NI", "15"), // Nicaragua
Map.entry("NE", "19"), // Niger
Map.entry("NG", "7.5"), // Nigeria
Map.entry("NU", "5"), // Niue
Map.entry("MK", "18"), // North Macedonia
Map.entry("NO", "25"), // Norway
Map.entry("PK", "17"), // Pakistan
Map.entry("PW", "10"), // Palau
Map.entry("PS", "16"), // Palestine
Map.entry("PA", "7"), // Panama
Map.entry("PG", "10"), // Papua New Guinea
Map.entry("PY", "10"), // Paraguay
Map.entry("PE", "18"), // Peru
Map.entry("PH", "12"), // Philippines
Map.entry("CG", "16"), // Republic of Congo
Map.entry("RU", "20"), // Russia
Map.entry("RW", "18"), // Rwanda
Map.entry("KN", "17"), // Saint Kitts and Nevis
Map.entry("VC", "15"), // Saint Vincent and the Grenadines
Map.entry("WS", "15"), // Samoa
Map.entry("SA", "15"), // Saudi Arabia
Map.entry("SN", "18"), // Senegal
Map.entry("RS", "20"), // Serbia
Map.entry("SC", "15"), // Seychelles
Map.entry("SL", "15"), // Sierra Leone
Map.entry("SG", "8"), // Singapore
Map.entry("ZA", "15"), // South Africa
Map.entry("KR", "10"), // South Korea
Map.entry("LK", "12"), // Sri Lanka
Map.entry("SD", "17"), // Sudan
Map.entry("CH", "7.7"), // Switzerland
Map.entry("TW", "5"), // Taiwan
Map.entry("TJ", "20"), // Tajikistan
Map.entry("TZ", "18"), // Tanzania
Map.entry("TH", "10"), // Thailand
Map.entry("TG", "18"), // Togo
Map.entry("TO", "15"), // Tonga
Map.entry("TT", "12.5"), // Trinidad and Tobago
Map.entry("TN", "18"), // Tunisia
Map.entry("TR", "18"), // Turkey
Map.entry("TM", "15"), // Turkmenistan
Map.entry("UG", "18"), // Uganda
Map.entry("UA", "20"), // Ukraine
Map.entry("AE", "5"), // United Arab Emirates
Map.entry("GB", "20"), // United Kingdom
Map.entry("UY", ""), // Uruguay
Map.entry("UZ", "12"), // Uzbekistan
Map.entry("VU", "13"), // Vanuatu
Map.entry("VN", "10"), // Vietnam
Map.entry("VE", "12"), // Venezuela
Map.entry("ZM", "16"), // Zambia
Map.entry("ZW", "15") // Zimbabwe
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.transform.vat.internal;

import static org.openhab.transform.vat.internal.VATTransformationConstants.*;

import java.math.BigDecimal;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.transform.TransformationException;
import org.openhab.core.transform.TransformationService;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This {@link TransformationService} adds VAT to the input according to configured country.
*
* @author Jacob Laursen - Initial contribution
*/
@NonNullByDefault
@Component(service = { TransformationService.class }, property = { "openhab.transform=VAT" })
public class VATTransformationService implements TransformationService {

private final Logger logger = LoggerFactory.getLogger(VATTransformationService.class);

@Override
public @Nullable String transform(String valueString, String sourceString) throws TransformationException {
QuantityType<?> source;
try {
source = new QuantityType<>(sourceString);
} catch (IllegalArgumentException e) {
logger.warn("Input value '{}' could not be converted to a valid number", sourceString);
throw new TransformationException("VAT Transformation can only be used with numeric inputs", e);
}
BigDecimal value;
try {
value = new BigDecimal(valueString);
} catch (NumberFormatException e) {
String rate = RATES.get(valueString);
if (rate == null) {
logger.warn("Input value '{}' could not be converted to a valid number or country code", valueString);
throw new TransformationException("VAT Transformation can only be used with numeric inputs", e);
}
value = new BigDecimal(rate);
}

return addVAT(source, value).toString();
}

private QuantityType<?> addVAT(QuantityType<?> source, BigDecimal percentage) {
return source.multiply(percentage.divide(new BigDecimal("100")).add(BigDecimal.ONE));
}
}
Loading

0 comments on commit f0b1e2a

Please sign in to comment.