Determining product inventory levels using Mongodb sales and purchase data

I attempted to develop a basic billing application. In this application, I am required to track the opening quantity of each product in my store, as well as sales and purchases linked to specific product IDs. To achieve this, I need to calculate the current stock for each product in my Products collection. You can check out the implementation on this Playground.

Here is an overview of the data stored in the collections:

[
    {
      "_id": ObjectId("6499d7eb72fb2552774c9f80"),
      "name": "Product 1",
      "openingStock": 10
    },
    {
      "_id": ObjectId("6499d81a72fb2552774c9f82"),
      "name": "Product 2",
      "openingStock": 10
    },
    {
      "_id": ObjectId("6499d83d72fb2552774c9f84"),
      "name": "Product 3",
      "openingStock": 20
    },
    {
      "_id": ObjectId("6499d86e72fb2552774c9f86"),
      "name": "Product 4",
      "openingStock": 15
    }
]

Data from Sales Collection:

[
    {
      "_id": ObjectId("64a559f68d79acbc66d96fdf"),
      "products": [
        {
          "product": ObjectId("6499d7eb72fb2552774c9f80"),
          "qty": 3
        },
        {
          "product": ObjectId("6499d83d72fb2552774c9f84"),
          "qty": 3
        } 
      ]
    },
    {
      "_id": ObjectId("64a559da8d79acbc66d96fde"),
      "products": [
        {
          "product": ObjectId("6499d7eb72fb2552774c9f80"),
          "qty": 3
        },
        {
          "product": ObjectId("6499d83d72fb2552774c9f84"),
          "qty": 1.5
        }
      ]
    }
]

Data from Purchase Collection:

[
    {
      "_id": ObjectId("64a5b540ffcbb3b942ccaae8"),
      "products": [
        {
          "product": ObjectId("6499d81a72fb2552774c9f82"),
          "qty": 2
        },
        {
          "product": ObjectId("6499d7eb72fb2552774c9f80"),
          "qty": 3.3
        }
      ]
    }
]

The expected result should look like the following:

[
  {
    "_id": ObjectId("6499d7eb72fb2552774c9f80"),
    "name": "Product 1",
    "stock": 7.3
  },
  {
    "_id": ObjectId("6499d81a72fb2552774c9f82"),
    "name": "Product 2",
    "stock": 12
  },
  {
    "_id": ObjectId("6499d83d72fb2552774c9f84"),
    "name": "Product 3",
    "stock": 15.5
  },
  {
    "_id": ObjectId("6499d86e72fb2552774c9f86"),
    "name": "Product 4",
    "stock": 15
  }
]

If you have any insights or solutions, please share them with me. Thank you.

Answer №1

To start, it is essential to combine three collections by performing two lookup operations with specific pipelines to unwind the sales and purchases collection. This approach focuses on merging individual products rather than the entire sale records.

After the merge process, calculations like sum and subtract are applied to the combined arrays and original fields.

Example in Mongoplayground

db.products.aggregate([
  {
    "$lookup": {
      "from": "sales",
      "let": {
        "id": "$_id"
      },
      "pipeline": [
        {
          "$unwind": "$products"
        },
        {
          "$match": {
            $expr: {
              "$eq": [
                "$products.product",
                "$$id"
              ]
            }
          }
        }
      ],
      "as": "sales"
    }
  },
  {
    "$lookup": {
      "from": "purchase",
      "let": {
        "id": "$_id"
      },
      "pipeline": [
        {
          "$unwind": "$products"
        },
        {
          "$match": {
            $expr: {
              "$eq": [
                "$products.product",
                "$$id"
              ]
            }
          }
        }
      ],
      "as": "purchases"
    }
  },
  {
    "$addFields": {
      "finalStock": {
        $sum: [
          {
            "$subtract": [
              "$openingStock",
              {
                "$sum": [
                  "$sales.products.qty",
                  
                ]
              }
            ]
          },
          {
            "$sum": [
              "$purchases.products.qty",
              
            ]
          }
        ]
      }
    }
  },
  {
    "$project": {
      _id: 1,
      name: 1,
      finalStock: 1
    }
  }
])

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Serve unique data to different bots and human visitors using express.js and node.js

I am looking for a method to differentiate between bot (such as google or bing) and human incoming requests, in order to provide tailored data to each. This could include serving json data for client-side javascript to build the site or preprocessed html. ...

Programmatically simulating a click on a link within a Windows Universal Windows Platform (U

I am facing an issue with a code that has multiple items with the same href attribute due to it being an external source. I need help figuring out how to programmatically click on a specific link tag using C# within a WebView or by accessing the source d ...

How can a JavaScript function communicate with a code behind method?

Currently, I am trying to implement a JavaScript function for an HTML img click event on an aspx page. Additionally, there is a server method in the code behind page that I need to call from the JavaScript function without any parameters whenever the user ...

Retrieve the HTML source code using AngularJS through an HTTP GET request

I came across a thread in the forum discussing a similar issue but unfortunately, it didn't have any answers. Let me explain my problem - I'm trying to validate a form using AngularJS and connect it by sending an HTTP request on submit. In my log ...

Comparison Between Object and Array

When inputting the values {2,4,45,50} in the console, 50 is displayed. However, assigning these values to a variable results in an error: var a = {2,4,45,50} Uncaught SyntaxError: Unexpected number Can you explain this concept? ...

Using a curly brace in a React variable declaration

After completing a react tutorial, I started customizing the code to suit my requirements. One specific section of the code involved a component that received a parameter called label. render() { const { label } = this.props; ... } For instance, I re ...

Navigating to a precise location on a webpage with React.js

I want to implement a straightforward action where the page automatically scrolls to a specific position upon loading. However, my attempts to execute this action have been unsuccessful so far. Is there an alternative method to achieve this in a React ap ...

Encountered an issue with accessing the 'reactiveProp' property which is undefined in vue-chartjs

While attempting to utilize a component known as "Vue-Chartjs" in order to create a LineChart, I encountered an error when trying to use the Line Chart demo. The specific error that popped up was: Uncaught TypeError: Cannot read property 'reactiveProp ...

When using jQuery to enable contenthover on divs, they will now start a new line instead of

I've been working on achieving a layout similar to this, with the contenthover script in action: Mockup Draft Of Desired Look However, the result I'm getting is different from what I expected, it can be seen here. The images are not aligning co ...

Looking to implement a CSS effect that will hide content without removing the space it occupies on the page?

Is there a way to hide specific buttons within the right column of a 3-column table display? I am currently utilizing jQuery to achieve this function. The purpose behind hiding these buttons is to prevent any quick clicks that might interfere with the fa ...

Is there a way to make a class method accessible in V8?

How can I make a class method accessible in a V8 context? I am trying to achieve something like the line below, but it's not working because lambda with captures cannot be treated as a function pointer. Global()->Set("foo",v8::FunctionTemplate::N ...

What steps might one take to address the undefined property error in node.js?

Facing an error message that says: Cannot read property 'title' of undefined Everything was functioning properly when using posts.forEach for traversal. However, encountered issues when switching to a for loop. Can anyone provide assistance? H ...

JS form submission problem

Seeking advice on developing a functional contact form using HTML, CSS, and JavaScript. All conditions currently validate properly, but encountering an issue with error messages persisting after re-entering the required fields. Additionally, looking to red ...

Is it possible for AJAX JSON response to return both accurate and undefined values sporadically?

In the process of developing JavaScript code to pinpoint the smallest unused number within a specified range of numbers, I encountered an issue with the AJAX request. Despite successfully retrieving all used numbers in the designated range, some undefined ...

I am interested in duplicating the li elements retrieved from a JSON source

$.getJSON("leftlist.json" , function(data) { $.each(data.articles,function(){ $('#ullist').before("<li id='mylic' style= color:blue class='item new"+cc+"'> "+el.name+"<div class='block'>&l ...

Employing a dynamic array within a module

Having some trouble using a reactive array in my component. It seems to work fine with an object, but when it comes to an array of objects, the view doesn't update as expected. Any suggestions on how to ensure the view gets updated when the array is ...

Attempting to craft a multi-filter feature using AngularJS that will allow for the precise filtering of JSON data based on both month and year identifiers

I have integrated AngularJS into the RoR framework and am working on creating a multi-filter for the "ng-repeat" function to filter JSON data based on "month_id" and "year_id". Here is the current code: JSON: [ { "date":"October 4, ...

Is there a way to dynamically import images in Next JS without having to place them in the public folder?

Currently, I am developing a textbook website in which authors contribute textbook folders containing markdown files and images: textbooks ├───textbook-1 │ ├───images │ └───markdown-files └───textbook-2 ├── ...

Different Option for Ajax/Json Data Instead of Using Multiple Jquery Append Operations

I am working on a complex data-driven application that heavily relies on Ajax and Javascript. As the amount of data returned for certain value selections increases, the application is starting to struggle. This is more of a brainstorming session than a q ...

Creating a jQuery-powered dynamic select field in Rails 3

After implementing the dynamic select functionality from this example on GitHub (GitHub Link), I successfully integrated dynamic selection for car models in my form for adding a new car. The form now filters car models based on the selected car name, and i ...