Skip to content

Commit

Permalink
feat: kampeerauto (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
hongaar committed Mar 17, 2023
1 parent 8132a54 commit 2803f58
Show file tree
Hide file tree
Showing 16 changed files with 454 additions and 64 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ node_modules
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# tests
coverage
29 changes: 9 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [CLI](#cli)
- [Installation](#installation)
- [Usage](#usage)
- [SDK](#sdk)
- [Installation](#installation-1)
- [Installation](#installation)
- [Usage](#usage-1)
- [Contributing](#contributing)
- [Roadmap](#roadmap)
Expand All @@ -32,28 +31,16 @@

# CLI

## Installation

```bash
yarn|npm add @motorrijtuigenbelasting/cli
```

## Usage

Show help:

```bash
# yarn
yarn dlx @motorrijtuigenbelasting/cli --help

# npm
npx @motorrijtuigenbelasting/cli --help
```
In the examples below, we use [`yarn dlx`](https://yarnpkg.com/cli/dlx) to run
the CLI. You can also use [`npx`](https://docs.npmjs.com/cli/v9/commands/npx),
it should work exactly the same.

Example with manual input:

```bash
yarn dlx|npx @motorrijtuigenbelasting/cli \
yarn dlx @motorrijtuigenbelasting/cli \
--vehicle-type Personenauto \
--weight 1051 \
--propulsion-type Benzine \
Expand All @@ -65,7 +52,7 @@ Example with vehicle ID (kenteken) as input:

```bash
export RDW_APP_TOKEN=foo
yarn dlx|npx @motorrijtuigenbelasting/cli \
yarn dlx @motorrijtuigenbelasting/cli \
--vehicle-id S-212-PK
```

Expand Down Expand Up @@ -116,8 +103,10 @@ Contributions are very welcome!
- [ ] implement missing propulsiontypes
- [ ] implement missing vehicletypes
- [ ] implement betalennaargebruik package
- [ ] emit warning when there is a known discrepancy between the model and the
official calculator

Also see [TODO.md](TODO.md).
See [TODO.md](TODO.md) for known problems which need fixing and general todos.

## Development

Expand Down
16 changes: 12 additions & 4 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
### TODOs

| Filename | line # | TODO |
| :------------------------------------------------------------------------------- | :----: | :-------------------------------------------------------------------- |
| [packages/mrb2023/tests/index.test.ts](packages/mrb2023/tests/index.test.ts#L34) | 34 | indien niet woonachtig in nederland, worden opcenten niet meegerekend |
| [packages/rdw/src/index.ts](packages/rdw/src/index.ts#L186) | 186 | add 115R-installatie |
| Filename | line # | TODO |
| :-------------------------------------------------------------------------------- | :----: | :-------------------------------------------------------------------- |
| [packages/mrb2023/tests/index.test.ts](packages/mrb2023/tests/index.test.ts#L46) | 46 | indien niet woonachtig in nederland, worden opcenten niet meegerekend |
| [packages/mrb2023/tests/index.test.ts](packages/mrb2023/tests/index.test.ts#L103) | 103 | we receive 1978 while the baseline gives 1977. not sure what is wrong |
| [packages/mrb2023/tests/index.test.ts](packages/mrb2023/tests/index.test.ts#L143) | 143 | we receive 52 while the baseline gives 65. not sure what is wrong |
| [packages/mrb2023/tests/index.test.ts](packages/mrb2023/tests/index.test.ts#L175) | 175 | this scenario is not covered in baseline calculator |
| [packages/mrb2023/tests/index.test.ts](packages/mrb2023/tests/index.test.ts#L182) | 182 | this scenario is not covered in baseline calculator |
| [packages/rdw/src/index.ts](packages/rdw/src/index.ts#L193) | 193 | add 115R-installatie |
| [packages/rdw/src/index.ts](packages/rdw/src/index.ts#L238) | 238 | this should be moved to mrb{revision} as it could change yoy |
| [packages/rdw/src/index.ts](packages/rdw/src/index.ts#L246) | 246 | De bestelauto moet minimaal 12 jaar oud zijn bij het begin van het |
| [packages/rdw/src/index.ts](packages/rdw/src/index.ts#L263) | 263 | bij het motorrijtuig vermeld staat dat het affabriek roetfilter |
| [packages/rdw/types/index.d.ts](packages/rdw/types/index.d.ts#L141) | 141 | this should be moved to mrb{revision} as it could change yoy |
3 changes: 3 additions & 0 deletions packages/betalennaargebruik/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ export default {
moduleNameMapper: {
"^(\\.{1,2}/.*)\\.js$": "$1",
},
// Somehow the default from ts-jest/presets/default-esm
// ([".ts", ".tsx", ".mts"]) throws an error
extensionsToTreatAsEsm: [".ts"],
};
57 changes: 46 additions & 11 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
VehicleType,
} from "@motorrijtuigenbelasting/core";
import mrb2023 from "@motorrijtuigenbelasting/mrb2023";
import { vehicleIdToParams } from "@motorrijtuigenbelasting/rdw";
import { fetchRdwData, rdwDataToParams } from "@motorrijtuigenbelasting/rdw";
import { command, program } from "bandersnatch";
import yaml from "js-yaml";

Expand All @@ -31,25 +31,35 @@ const cmd = command()
choices: Object.values(VehicleType),
})
.option("weight", {
description: "Weight",
description: "Weight (in kg)",
type: "number",
})
.option("propulsion-type", {
description: "Propulsion type",
type: "string",
choices: Object.values(PropulsionType),
})
.option("propulsion-emission", {
description: "Propulsion emission",
.option("co2-emission", {
description: "CO₂ emission (in g/km)",
type: "number",
})
.option("particulate-matter-surtax", {
description:
"Does the particulate matter surtax apply? Only valid if --propulsion-type=Diesel",
type: "boolean",
})
.option("rented-for-business-purposes", {
description:
"Is your motorhome rented out for business purposes? Only valid if --vehicle-type=Kampeerauto",
type: "boolean",
})
.option("province", {
description: "Province",
type: "string",
choices: Object.values(Province),
})
.option("mileage", {
description: "Mileage per period",
description: "Mileage per period (in km)",
type: "number",
default: 2500,
})
Expand All @@ -63,18 +73,26 @@ const cmd = command()
choices: ["js", "json", "yaml", "table"] as const,
default: "js",
})
.option("log-rdw-data", {
description:
"Log RDW output. Only if --vehicle-id is set. Sets format to js",
type: "boolean",
})
.action(
async ({
"vehicle-id": vehicleId,
"rdw-app-token": rdwAppToken,
"vehicle-type": vehicleType,
weight,
"propulsion-type": propulsionType,
"propulsion-emission": propulsionEmission,
"co2-emission": co2Emission,
"particulate-matter-surtax": particulateMatterSurtax,
"rented-for-business-purposes": rentedForBusinessPurposes,
province,
mileage,
period,
format,
"log-rdw-data": logRdwData,
}) => {
let params: Params;

Expand All @@ -85,21 +103,36 @@ const cmd = command()

if (
typeof propulsionType !== "undefined" ||
typeof propulsionEmission !== "undefined" ||
typeof co2Emission !== "undefined" ||
typeof particulateMatterSurtax !== "undefined" ||
typeof vehicleType !== "undefined" ||
typeof weight !== "undefined"
) {
throw new InvalidArgument(
"cannot specify propulsion-type, propulsion-emission, vehicle-type or weight when kenteken is specified"
"cannot specify --propulsion-type, --propulsion-co2-emission, --vehicle-type, --particulate-matter-surtax or --weight when --vehicle-id is specified"
);
}

params = await vehicleIdToParams(vehicleId, rdwAppToken);
const rdwData = await fetchRdwData(vehicleId, rdwAppToken);

if (logRdwData) {
console.dir(rdwData, { depth: null });
format = "js";
}

params = rdwDataToParams(rdwData);
} else {
params = {
vehicleType,
weight,
propulsions: [{ type: propulsionType, emission: propulsionEmission }],
propulsions: [
{
type: propulsionType,
co2Emission: co2Emission || null,
},
],
particulateMatterSurtax: particulateMatterSurtax ?? null,
rentedForBusinessPurposes: rentedForBusinessPurposes ?? null,
};
}

Expand Down Expand Up @@ -139,7 +172,9 @@ const cmd = command()
propulsions: params.propulsions
.map(
(propulsion) =>
`${propulsion.type} (emission: ${propulsion.emission})`
`${propulsion.type} (CO₂ emission: ${
propulsion.co2Emission ?? "unknown"
} g/km)`
)
.join(", "),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ afterEach(() => {

test("requires rdw-app-token", async () => {
await expect(() =>
app.run('--kenteken x --rdw-app-token ""')
app.run('--vehicle-id x --rdw-app-token ""')
).rejects.toThrow("Invalid argument (missing rdw-app-token)");
// expect(outputSpy.mock.calls[0]![0]).toStrictEqual({ kenteken: "x" });
});
10 changes: 7 additions & 3 deletions packages/core/src/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export enum PropulsionType {

export type Propulsion = {
type: PropulsionType;
emission: number | null;
co2Emission: number | null; // g/km
};

export type Params = {
Expand All @@ -51,6 +51,10 @@ export type Params = {
weight: number;
province?: Province | null;
mileage?: number;

// Special cases
particulateMatterSurtax?: boolean | null;
rentedForBusinessPurposes?: boolean | null;
};

export function containsPropulsionType(
Expand All @@ -67,12 +71,12 @@ export function containsPropulsionType(
export function highestPropulsionEmission(
propulsions: Propulsion[]
): number | null {
if (propulsions.some((propulsion) => propulsion.emission === null)) {
if (propulsions.some((propulsion) => propulsion.co2Emission === null)) {
return null;
}

return Math.max(
...propulsions.map((propulsion) => propulsion.emission as number)
...propulsions.map((propulsion) => propulsion.co2Emission as number)
);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/core/tests/model.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Period, run, Unit } from "../src/model.js";
import { PropulsionType, VehicleType } from "../src/params.js";
import { Params, PropulsionType, VehicleType } from "../src/params.js";

test("runs a simple model", () => {
const params = {
const params: Params = {
vehicleType: VehicleType.Personenauto,
weight: 1000,
propulsions: [{ type: PropulsionType.Benzine, emission: 100 }],
propulsions: [{ type: PropulsionType.Benzine, co2Emission: 100 }],
};

const model = () => {
Expand Down
9 changes: 8 additions & 1 deletion packages/mrb2023/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
NotImplementedError,
VehicleType,
} from "@motorrijtuigenbelasting/core";
import { personenauto } from "./vehicleTypes/index.js";
import { kampeerauto, personenauto } from "./vehicleTypes/index.js";

const model: Model = (params) => {
const {
Expand Down Expand Up @@ -48,6 +48,13 @@ const model: Model = (params) => {
* https://www.belastingdienst.nl/wps/wcm/connect/bldcontentnl/belastingdienst/prive/auto_en_vervoer/belastingen_op_auto_en_motor/motorrijtuigenbelasting/soort_motorrijtuig/personenauto
*/
return personenauto(params);

case VehicleType.Kampeerauto:
/**
* Kampeerauto (camper)
* https://www.belastingdienst.nl/wps/wcm/connect/bldcontentnl/belastingdienst/prive/auto_en_vervoer/belastingen_op_auto_en_motor/motorrijtuigenbelasting/bijzonder_tarief/kampeerauto-camper
*/
return kampeerauto(params);
}

throw new NotImplementedError();
Expand Down
52 changes: 51 additions & 1 deletion packages/mrb2023/src/rates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const rateMap = {
surtaxes: {
/**
* Wet op de motorrijtuigenbelasting 1994
* Artikel 23
* Artikel 23, tweede lid
* Geldig op 1-1-2023
* https://wetten.overheid.nl/BWBR0006324/2023-01-01#HoofdstukIV
*/
Expand Down Expand Up @@ -73,6 +73,56 @@ export const rateMap = {
},
},
],
/**
* Wet op de motorrijtuigenbelasting 1994
* Artikel 23, tweede lid
* Geldig op 1-1-2023
* https://wetten.overheid.nl/BWBR0006324/2023-01-01#HoofdstukIV
*/
[PropulsionType["LPG en overige (behalve elektriciteit en waterstof)"]]: [
{
threshold: 0,
fixedAmount: 86.25,
},
{
threshold: 600,
fixedAmount: 103.39,
},
{
threshold: 700,
fixedAmount: 120.54,
},
{
threshold: 800,
fixedAmount: 137.65,
},
{
threshold: 900,
fixedAmount: 150.36,
variable: {
amount: 15.92,
},
},
],
/**
* Wet op de motorrijtuigenbelasting 1994
* Artikel 23, derde lid
* Geldig op 1-1-2023
* https://wetten.overheid.nl/BWBR0006324/2023-01-01#HoofdstukIV
*/
[PropulsionType["LPG3 en Aardgas"]]: [
{
threshold: 0,
fixedAmount: 0,
},
{
threshold: 900,
fixedAmount: 16.64,
variable: {
amount: 16.64,
},
},
],
},
},
} as RateMap;
1 change: 1 addition & 0 deletions packages/mrb2023/src/vehicleTypes/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./kampeerauto.js";
export * from "./personenauto.js";
Loading

0 comments on commit 2803f58

Please sign in to comment.