This macro generates and emails a dynamic "Top Products" sales report. It is designed to help you identify which products are driving your revenue, how their performance compares to previous periods, and what their current inventory status is.
The final output is a clean, table-based HTML email sent to a specified client, complete with actionable alerts for marketing and restocking.
The macro's power comes from its ability to compare three different time periods. When you run the macro, you define the length (in days) for these three periods.
Here is how the time periods are calculated, running backwards from today:
[...Benchmark Period...] <-- [Comparison Period] <-- [Report Period] <-- [Today]
Based on this analysis, the macro generates two types of alerts for the Top X products:
This is how the final email looks to the client, showing key performance indicators and actionable alerts based on the defined periods.
Hello John, here is your report.
| Rank / SKU | Units / Revenue | Benchmarks (vs. 7d / 30d Avg) | Inventory | Channel Breakdown |
|---|---|---|---|---|
| 1. SKU-ALPHA-1 Premium Widget (Red) |
Units: 150 Revenue: $4,500.00 ASP: $30.00 (55.6% of Total) |
vs. Prior 7d: +25% vs. 30d Avg: +60% |
Stock: 50 Days Left: 1.7 🚨 |
EBAY: 100 AMAZON: 50 |
| 2. SKU-BETA-2 Standard Gadget (Blue) |
Units: 90 Revenue: $1,800.00 ASP: $20.00 (22.2% of Total) |
vs. Prior 7d: -10% vs. 30d Avg: -5% |
Stock: 500 Days Left: 16.7 |
WEBSITE: 80 ETSY: 10 |
Marketing Alerts:
Restock Alerts:
To set up this macro, you must configure it in the Linnworks script execution settings. The Execute method requires 11 parameters to be passed in.
| Parameter Name | Type | Description | Example |
|---|---|---|---|
| Report Parameters | |||
reportPeriodDays |
Integer | The main period for the report (e.g., "Top 5 from last 7 days"). | 7 |
comparisonPeriodDays |
Integer | The period to compare against (e.g., "vs. the 7 days before that"). | 7 |
benchmarkPeriodDays |
Integer | The period to use for the long-term sales average (e.g., "30-day avg"). | 30 |
topAmount |
Integer | The number of top products to show (e.g., Top 5, Top 10). | 5 |
| Email Sender (Your) Details | |||
senderEmail |
String | The "From" email address (e.g., your report's email). | reports@mycompany.com |
senderName |
String | The "From" name (e.g., "MyCompany Reports"). | Patternica Reports |
smtpHost |
String | The SMTP server host. | smtp.gmail.com |
smtpPort |
Integer | The SMTP port (e.g., 587 for TLS). | 587 |
smtpPassword |
String | The password for the senderEmail account. (See note below on App Passwords) |
YourAppPassword |
| Email Recipient (Client) Details | |||
clientEmail |
String | The client's email address to send the report to. | client@example.com |
clientName |
String | The client's name, used in the email greeting (e.g., "Hello John,"). | John |
For security reasons, standard email passwords will often fail when used in automated applications like this macro. You must use an App Password for the smtpPassword parameter if your email account uses 2-Factor Authentication (2FA) or requires a more secure connection.
An App Password is a long, randomly generated password that you create specifically for an application. For example, if you are using a Google (Gmail) account, you can find instructions on how to generate one here: How to sign in with App Passwords (Google Support).
Here is how you would combine the parameters to generate different types of reports:
Goal: See yesterday's Top 5 vs. the day before, using a 7-day average for stocking.
reportPeriodDays: 1comparisonPeriodDays: 1benchmarkPeriodDays: 7Goal: See the last 7 days' Top 5 vs. the previous 7 days, using a 30-day average for stocking.
reportPeriodDays: 7comparisonPeriodDays: 7benchmarkPeriodDays: 30Goal: See the last 30 days' Top 10 vs. the previous 30 days, using a 90-day average for stocking.
reportPeriodDays: 30comparisonPeriodDays: 30benchmarkPeriodDays: 90topAmount: 10