diff --git a/src/Head.js b/src/Head.js
index a90058afe40269f25bcf55ce0c9cc78987fd519b..7376b551140821e7b2f5eb2abe4f28ea1454b6c6 100644
--- a/src/Head.js
+++ b/src/Head.js
@@ -28,6 +28,9 @@ function Head(props) {
         <LinkContainer to="/transaction">
           <NavDropdown.Item>Transacciones</NavDropdown.Item>
         </LinkContainer>
+        <LinkContainer to="/annual">
+          <NavDropdown.Item>Listado Anual</NavDropdown.Item>
+        </LinkContainer>
       </NavDropdown>
     );
   }
diff --git a/src/Panel.js b/src/Panel.js
index a97ac13bac5e4efe4ca704825aa8d361e1cca1aa..7cd86524dac9f37f91b77ed2187aa32406e09354 100644
--- a/src/Panel.js
+++ b/src/Panel.js
@@ -5,6 +5,7 @@ import MemberAdder from "./member/MemberAdder";
 import MemberEditer from "./member/MemberEditer";
 import MemberList from "./member/MemberList";
 import ProductList from "./product/ProductList";
+import AnnualReport from "./product/AnnualReport";
 import ShowProduct from "./product/ShowProduct";
 import CreateProduct from "./product/CreateProduct";
 import Inventary from "./inventary/Inventary";
@@ -56,6 +57,9 @@ function LogedPanel(props) {
             <Route path="/products">
               <ProductList />
             </Route>
+            <Route path="/annual">
+              <AnnualReport />
+            </Route>
             <Route path="/product/add">
               <CreateProduct />
             </Route>
diff --git a/src/product/AnnualReport.js b/src/product/AnnualReport.js
new file mode 100644
index 0000000000000000000000000000000000000000..f253f315cd60aa21fcc97d821c1036d9df9ff543
--- /dev/null
+++ b/src/product/AnnualReport.js
@@ -0,0 +1,96 @@
+import React, { useState } from "react";
+import Fetcher from "../Fetcher";
+import { date2string } from "../util";
+
+function transactionsPerMonth(transactions) {
+  let productsPerMonth = {};
+
+  const incProduct = (date, name, amount) => {
+    if (amount === 0) {
+      return;
+    }
+
+    const strDate = String(date.getFullYear()) + " - " + (date.getMonth() + 1);
+    if (productsPerMonth[strDate] === undefined) {
+      productsPerMonth[strDate] = {};
+    }
+    if (productsPerMonth[strDate][name] === undefined) {
+      productsPerMonth[strDate][name] = amount;
+    } else {
+      productsPerMonth[strDate][name] += amount;
+    }
+  };
+
+  transactions.forEach((t) => {
+    const date = new Date(Date.parse(t.date));
+    const monthDate = new Date(date.getFullYear(), date.getMonth());
+    switch (t.type) {
+      case "purchase":
+        t.purchase.forEach((e) =>
+          incProduct(monthDate, e.product.name, e.amount)
+        );
+        break;
+      case "order":
+        t.order_purchase.forEach((e) =>
+          incProduct(monthDate, e.order_product.product.name, e.amount)
+        );
+        break;
+      default:
+        return;
+    }
+  });
+
+  return productsPerMonth;
+}
+
+function AnnualReport() {
+  const [data, setData] = useState([]);
+
+  const setTransactions = (transactions) => {
+    const d = transactionsPerMonth(transactions);
+    setData(d);
+  };
+
+  let dates = Object.keys(data);
+  dates = dates.sort((a, b) => b.localeCompare(a));
+  const months = dates.map((date) => {
+    let products = Object.keys(data[date]);
+    console.log(data);
+    products = products.sort((a, b) =>
+      data[date][a] < data[date][b] ? 1 : -1
+    );
+    console.log(products);
+    const productList = products.map((product) => (
+      <li key={date + "-" + product}>
+        {product}: {data[date][product]}
+      </li>
+    ));
+    return (
+      <div>
+        <h3>{date}</h3>
+        <ul>{productList}</ul>
+      </div>
+    );
+  });
+
+  const now = new Date();
+  const end = date2string(now);
+  const start = date2string(new Date(now.getFullYear() - 1, now.getMonth()));
+  return (
+    <Fetcher
+      url={
+        "/api/transaction?start-date=" +
+        start +
+        "&end-date=" +
+        end +
+        "&type=purchase&type=order"
+      }
+      onFetch={setTransactions}
+      oneShot
+    >
+      {months}
+    </Fetcher>
+  );
+}
+
+export default AnnualReport;