Skip to content

Instantly share code, notes, and snippets.

@klaemo
Created March 21, 2015 14:34
Show Gist options
  • Save klaemo/2d68a52ad04d99217eca to your computer and use it in GitHub Desktop.
Save klaemo/2d68a52ad04d99217eca to your computer and use it in GitHub Desktop.
inventory
/*
Products flow from one location to another. This is tracked with deliveries.
Delivery:
amount
sourceId
targetId
productId
*/
Delivery.belongsTo(Location, { as: 'source' })
Delivery.belongsTo(Location, { as: 'target' })
Delivery.belongsTo(Product, { as: 'product' })
// how to compute the stock/inventory of each product in each location?
// stock = inward_flow - outward_flow (for each product and location)
// inward_flow = sum(amount) where location is target
// outward_flow = sum(amount) where location is source
@mickhansen
Copy link

Product.findAll({
  include: [
    {
      model: Delivery,
      attributes: [
        ['SUM(product.delivery.source.id)', 'in'],
        ['SUM(product.delivery.target.id)', 'out']
      ],
      include: [
        {model: Location, as: 'source'},
        {model: Location, as: 'target'}
      ]
    }
  ],
  group: [
    'product.delivery.id',
    'product.id'
  ]
});

@klaemo
Copy link
Author

klaemo commented Mar 21, 2015

This is the SQL that does what I want.

SELECT
    "Locations".id, "Locations".name, "Products".id,
    SUM((CASE
        WHEN l.id = transactions."sourceId"
            THEN transactions.units * -1
            ELSE transactions.units
    END))
FROM
    "Locations"
INNER JOIN transactions ON "Locations".id = transactions."sourceId" OR "Locations".id = transactions."targetId"
INNER JOIN "Products" ON transactions."productId" = "Products".id
GROUP BY "Locations".id, "Products".id

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment