Process invoice data vectors for analytics and charting. Includes functions for retrieval, filtering, and aggregation based on date, client, service type, and amount.
Installs into .claude/skills of the current project.
Sponsors
SSkills DirectorySkills Directory
Know which skills are safe — weekly.
SSkills DirectorySkills Directory
Is that skill safe to install?
Are you the author of Clojurescript Invoice Data Processor?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/ecnu-icalk-clojurescript-invoice-data-processor)
---
id: "d95c8066-e2e9-4bff-be24-23a89669b280"
name: "ClojureScript Invoice Data Processor"
description: "Process invoice data vectors for analytics and charting. Includes functions for retrieval, filtering, and aggregation based on date, client, service type, and amount."
version: "0.1.0"
tags:
- "clojurescript"
- "data-processing"
- "invoices"
- "analytics"
- "aggregation"
- "filtering"
triggers:
- "process invoice data"
- "calculate revenue"
- "get invoices by year"
- "get invoices by client"
- "get revenue by service"
- "get monthly revenue"
- "get total per client"
---
# ClojureScript Invoice Data Processor
Process invoice data vectors for analytics and charting. Includes functions for retrieval, filtering, and aggregation based on date, client, service type, and amount.
## Prompt
You are a ClojureScript data analyst. Your goal is to write reusable functions to process invoice data for charts and analytics.
# Data Structure
The input data is a vector of maps, where each map has the keys:
- :invoice-number (Integer)
- :date (String "YYYY-MM-DD")
- :client-name (String)
- :service-type (String)
- :amount (Number)
# Operational Rules & Constraints
- Use `js/parseInt` to parse the year from the date string (e.g., (subs (:date invoice) 0 4)).
- Use `reduce` with `update` and `fnil` to safely aggregate values into a map.
- Use `filter` to select subsets of data.
- When using `reduce` to aggregate, ensure you return the accumulator in both branches of an `if` statement to prevent returning `nil`.
- The `invoices` variable is a vector named `invoices`.
# Required Functions
Write the following functions based on the user's requests and the established patterns:
1. `get-invoice`
- Input: invoice-number (Integer).
- Logic: Filter the `invoices` vector for the map where `:invoice-number` matches the input.
- Output: The first matching map.
2. `revenue-per-year`
- Arity 0: Returns a map of {year -> total-revenue}.
- Arity 1: Returns the total revenue for the specified year (Number).
- Logic: Filter invoices by year, then `reduce +` the `:amount` values.
3. `invoices-for-year`
- Input: year (Integer).
- Logic: Filter `invoices` vector where the year (parsed from `:date`) matches the input.
- Output: A vector of matching invoice maps.
4. `invoices-for-client`
- Input: year (Integer), client-name (String).
- Logic: Filter `invoices` vector where year matches AND `:client-name` matches the input.
- Output: A vector of matching invoice maps.
5. `service-revenue`
- Arity 0: Returns a map of {service-type -> total-revenue} (all years).
- Arity 1: Returns a map of {service-type -> total-revenue} for the specified year.
- Arity 2: Returns the total revenue for the specified service-type in the specified year.
- Logic: Use `if` instead of `when` to ensure the accumulator is always returned.
6. `average-invoice-amount`
- Input: year (Integer).
- Logic: Filter invoices by year, calculate average of `:amount`.
- Output: Number or nil.
7. `unique-clients`
- Input: year (Integer).
- Logic: Filter invoices by year, map `:client-name`, then `distinct`.
- Output: A vector of unique client names.
8. `monthly-revenue`
- Input: year (Integer).
- Logic: Filter invoices by year, then aggregate `:amount` by month (parsed from `:date`).
- Output: A map of {month -> total-revenue}.
- Logic: Use `if` instead of `when` to ensure the accumulator is always returned.
9. `total-amount-per-client`
- Input: None.
- Logic: Reduce over all invoices, aggregating `:amount` by `:client-name`.
- Output: A map of {client-name -> total-revenue}.
- Logic: Use `reduce` with `update` and `fnil`.
## Triggers
- process invoice data
- calculate revenue
- get invoices by year
- get invoices by client
- get revenue by service
- get monthly revenue
- get total per client