What is the total amount within a specified date range when retrieved as JSON?

Consider the following JSON structure:

{
    "timesheets": [
        {
            "user": {
                "username": "erik",
                "first_name": "Erik",
            },
            "project_id": 4,
            "calc_full_week": {
                "2020-06-22": 5,
                "2020-06-23": 10,
                "2020-06-24": 8,
                "2020-06-25": 13,
                "2020-06-26": null,
                "2020-06-27": null,
                "2020-06-28": null
            }
        },
        {
            "user": {
                "username": "erik",
                "first_name": "Erik",
            },
            "project_id": 4,
            "calc_full_week": {
                "2020-06-29": 15,
                "2020-06-30": 10,
                "2020-07-01": null,
                "2020-07-02": null,
                "2020-07-03": null,
                "2020-07-04": null,
                "2020-07-05": null
            }
        },
        {
            "user": {
                "username": "rawwe",
                "first_name": "joey",
            },
            "project_id": 4,
            "calc_full_week": {
                "2020-06-22": 3,
                "2020-06-23": 10.4,
                "2020-06-24": 8,
                "2020-06-25": 8,
                "2020-06-26": 8,
                "2020-06-27": 8,
                "2020-06-28": 5
            }
        }
    ]
}

I am seeking an efficient way to extract the sum of values from calc_full_week within a specified range. For example, if I provide the range 2020-06-25 - 2020-07-03, the total sum of values within that range should be calculated (13+15+10+8+8+8+5 for the given JSON).

Now, the dilemma is whether to perform these calculations on the backend (django) or using JavaScript on the client side.

In my Django model, the structure is as shown below:


class Timesheet(Model):
    year = PositiveIntegerField(validators=[MaxValueValidator(2500), MinValueValidator(1900)])
    week = PositiveIntegerField()
    project = ForeignKey("projects.Project", on_delete=CASCADE)
    user = ForeignKey("accounts.User", on_delete=CASCADE)
    day_1 = DecimalField("monday", blank=True, null=True, max_digits=4, decimal_places=1)
    day_2 = DecimalField("tuesday", blank=True, null=True, max_digits=4, decimal_places=1)
    day_3 = DecimalField("wednesday", blank=True, null=True, max_digits=4, decimal_places=1)
    day_4 = DecimalField("thursday", blank=True, null=True, max_digits=4, decimal_places=1)
    day_5 = DecimalField("friday", blank=True, null=True, max_digits=4, decimal_places=1)
    day_6 = DecimalField("saturday", blank=True, null=True, max_digits=4, decimal_places=1)
    day_7 = DecimalField("sunday", blank=True, null=True, max_digits=4, decimal_places=1)

I serialize this data and include a

 calc_full_week = serializers.SerializerMethodField()
attribute, with the calculation logic detailed in the method below:

 def get_calc_full_week(self, obj):
        current_week = obj.week
        current_year = obj.year
        # Since week 1 corresponds to week 0
        week = current_week - 1
        # List containing each date of a given week
        startdate = time.asctime(time.strptime('%d %d 1' % (current_year, week), '%Y %W %w'))
        startdate = datetime.datetime.strptime(startdate, '%a %b %d %H:%M:%S %Y')

        date_dict = {}
        days_in_week = [obj.day_1, obj.day_2, obj.day_3, obj.day_4, obj.day_5, obj.day_6, obj.day_7]
        for i in range(0, 7):
            day = startdate + datetime.timedelta(days=i)
            date_dict[day.strftime('%Y-%m-%d')] = days_in_week[i]

        return date_dict

Answer №1

const data = {
    "statistics": [
        {
            "user": {
                "username": "erik",
                "first_name": "Erik",
            },
            "project_id": 4,
            "weekly_hours": {
                "2020-06-22": 5,
                "2020-06-23": 10,
                "2020-06-24": 8,
                "2020-06-25": 13,
                "2020-06-26": null,
                "2020-06-27": null,
                "2020-06-28": null
            }
        },
        {
            "user": {
                "username": "erik",
                "first_name": "Erik",
            },
            "project_id": 4,
            "weekly_hours": {
                "2020-06-29": 15,
                "2020-06-30": 10,
                "2020-07-01": null,
                "2020-07-02": null,
                "2020-07-03": null,
                "2020-07-04": null,
                "2020-07-05": null
            }
        },
        {
            "user": {
                "username": "rawwe",
                "first_name": "joey",
            },
            "project_id": 4,
            "weekly_hours": {
                "2020-06-22": 3,
                "2020-06-23": 10.4,
                "2020-06-24": 8,
                "2020-06-25": 8,
                "2020-06-26": 8,
                "2020-06-27": 8,
                "2020-06-28": 5
            }
        }
    ]
}

const calculateTotalHours = (startDate, endDate) => {
  const startRange = +startDate.split('-').join('')
  const endRange = +endDate.split('-').join('')
  let totalHours = 0
  data.statistics.reduce((acc, val) => {
    Object.keys(val.weekly_hours).map((date, index) => {
      const dateSplit = +date.split('-').join('')
      if (dateSplit >= startRange && dateSplit <= endRange) {
        totalHours += val.weekly_hours[date]
      }
    })
  }, 0)
  return totalHours
}

console.log(calculateTotalHours('2020-06-25', '2020-07-03'))

Answer №2

If you're interested in achieving this task using Python, consider the following approach:

Start by creating a list of allowed dates:

my_date_range = ['2020-06-25', '2020-06-26', ]

It would be beneficial to have a separate method that generates this list based on a specified start and end date, like the one suggested in this Stack Overflow answer.

To simplify the extraction of required sub-nodes from nested dictionaries or JSON objects, you can leverage a library like dpath:

import json
import dpath

data = json.loads(json_string)  # convert JSON string to dictionary format

# filter the dictionary for all date values within a certain range
# utilizing wildcard (*) for flexibility in key name filtering
# setting yielded=True returns a generator for tuples instead of a dictionary
result = dpath.util.search(data, "timesheets/*/calc_full_week/2020-*", yielded=True)

# Calculate the sum of the required dates while filtering out None values
my_sum = sum(filter(None, [v for k, v in result if k in my_date_range]))

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

Setting the default selection in AngularJS based on the URL entered

I've encountered an issue with a dropdown menu in my AngularJS version 1.4 application. The dropdown menu contains links to different sections of the page. The problem arises when I directly enter the page URL - instead of selecting the correct link f ...

retrieve the identification number associated with a specific value

How can I retrieve the value of this ID, which is sent from the controller and displayed in the table? This is my HTML code: <tbody class="no-border-x"> <tr> <td id="id"></td> <td id="nm_kegiatan"></td> ...

validating API keys in Django

What is the process for verifying API keys in Django? I am currently using RapidAPI and they provide a key, but how can I authorize it with the URL? views.py def thanks(request): url = "https://webknox-trivia-knowledge-facts-v1.p.rapidapi.com/trivia/r ...

Using Sequelize to Include Model Without Specifying Table Name

I am new to Sequelize I am facing an issue with "Nested Eager Loading" I have 2 tables with a one-to-many relationship Comment Table User Table This is the code I am using for the query Comment.findAll({ include: [User] }) The result I got was ...

Nightwatch failing to locate element within iFrame

I'm currently facing a challenge when trying to access an element within an iframe. Despite successfully switching to the frame, Nightwatch keeps returning "element not found" whenever I attempt to verify its presence or visibility. Below is a snippe ...

What is preventing my CSS variables from functioning in my Vue component that is utilizing SASS?

Currently, I am working with sass and vue version-3. Within one of my components, the following code is present: HelloWorld.vue : <template> <div class="greetings"> <h1>{{ msg }}</h1> <h3> You’ve succe ...

What is causing this error/bug to show up in Angular?

I encountered an error while working on my Angular project that incorporates both front-end and back-end development with Python Flask. Even though the page updates correctly, a database-related error is being displayed in the console. Below are the snippe ...

"Utilize gulp-connect to store the root as an array

The gulp-connect documentation mentions that options.root can accept either an array or string. My situation involves having a build directory that I want to use as the root, along with a separate sources directory where all my source maps are located. Is ...

Scrollable content with sticky positioning using CSS3 and JavaScript

I successfully implemented a sidebar using the position: sticky property and it is functioning perfectly. To identify colors in the following text, refer to the script below. When scrolling, the black area remains fixed while the green area sticks to its ...

Django: Sending Templates through AJAX for Dynamic Rendering

Hey there, this is more of a theoretical question. So I recently discovered a cool trick: using AJAX to trigger a function that delivers a pre-rendered HTML template as a response, which can then be applied to a designated div element. This method feels i ...

What is the best way to eliminate the border of an expansion panel in Material-UI?

Is there a way to eliminate the border surrounding the expansion panel in Material-UI? ...

Can the ajaxsetup error handler be used with the POST method?

I have a strange question - does the global error handler applied when using ajaxsetup get triggered in case of an Ajax error on a POST request? I've tried handling Ajax errors in several places, but the error handler is only being hit for GET reques ...

Start up a server-side JavaScript instance utilizing Express

My journey into web programming has led me to learning JavaScript, Node.js, and Express.js. My ultimate goal is to execute a server-side JavaScript function (specifically a function that searches for something in a MySQL database) when a button is pressed ...

"Return to the top" feature that seamlessly integrates with jQuery's pop-up functionality

Currently, I am facing an issue with a jQuery selectmenu list that opens as a popup due to its length. My goal is to add a "back to top" button at the end of the list. While researching online, I came across this tutorial which seems promising, but unfor ...

Having trouble with my unique 404 page templates not functioning properly in Django

I'm having trouble implementing my custom 404 and 403 error pages for my Django project. I've previously used the same code in other projects, but it's not functioning as expected this time. Here is the function I am using: def error_404(re ...

Information released by JavaScript through AJAX and JSON

Hello everyone, I've been trying to merge two different Ajax codes together and it's been quite a challenge. As a novice, I know I may sound ridiculous but I really need some help... My goal is to convert an array into JSON and display the data ...

How can you center popup windows launched from the main window using jquery?

Within my web application, I frequently utilize popup windows that open at different locations on the screen. These popups are standard windows created with window.open() rather than using Jquery. Now, I am seeking a solution to automatically center all p ...

Is there a way to verify that all of my HTML elements have been loaded in AngularJS?

I am currently utilizing angularJS version 1.2.1 along with angular-ui-bootstrap. Within my code, I have a collection of <ng-includes> tags from angularjs and <accordion> components from angular-ui. When loading the content, I need to initiat ...

Encountered an issue while trying to access the length property of an undefined value within an aside

I am currently utilizing ng-strap's modal, alert, and aside features. Each of them is functioning properly on their own, but when I attempt to place an alert or modal inside an aside, it throws the following error: Uncaught TypeError: Cannot read p ...

sending the AJAX request from back to the original JavaScript function

Here presents an issue. I am dealing with an HTML Form that contains a submit button with an onclick=validationFunction(). When this button is clicked, the form values are passed to the mentioned function. Within this function, the form values undergo va ...