Reputation: 137
I am new user in Python, I have a problem with the None
type, I looked different question, but the problem persists.
My code is looking for Friday and Saturday between two dates, so far it works, but when I sum both I have this error:
"TypeError: unsupported operand type (s) for +: 'NoneType' and 'NoneType'
After I return the result in the function.
Here's my code :
# -*- coding: utf-8 -*-
import datetime
import calendar
calendar.setfirstweekday(calendar.SUNDAY)
from odoo import models, fields, api
class HrMission(models.Model):
_name = "hr.employee.mission"
_description = "hr mission"
_inherit = "hr.employee.mission"
days_compensation =fields.Float(compute='get_compensation', compstring='Jours de récupération', help="Jours de récupération si la mission contient les jours de repos",
required=True, readonly=True,)
@api.multi
@api.depends('mission_start_date', 'mission_end_date')
def get_compensation(self):
for rec in self:
if rec.mission_start_date and rec.mission_end_date:
time1 = datetime.datetime.strptime(rec.mission_start_date, "%Y-%m-%d")
time2 = datetime.datetime.strptime(rec.mission_end_date, "%Y-%m-%d")
week = {}
leave_value = {}
# Compute Number Of Friday And Saturday
for i in range((time2 - time1).days):
day = calendar.day_name[(time1 + datetime.timedelta(days=i+1)).weekday()]
week[day] = week[day] + 1 if day in week else 1
fri = week.get('Friday') # Result Number 4 Of Friday If "Start Date", "End date" --> "01/01/2017", "31/01/2017"
sat = week.get('Saturday') # Same thing that friday
friandsat = mon + sat # Error ---> "TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'"
rec.days_compensation = friandsat
Upvotes: 1
Views: 8555
Reputation: 21
I think you can return Fridays and Saturdays between two dates by using datetime
format. That is all. And a condition to check if the day name is the required one or not.
This format prints the day name: "%A"
Upvotes: 0
Reputation: 1318
This is for someone arriving here from search engines. I faced this error while importing data. This happened because I had the product id field mapped to Product
instead of Product/External ID
. So if you got this error while importing data, check whether the id fields are mapped properly.
Upvotes: 0
Reputation: 2821
datetime.datetime(2019, 3, 1)
, then should the answer be 1
? ...
def get_compensation(self):
def date_range_inclusive(rec):
# if either date is undefined, then so is date range
if not rec.mission_end_date or not rec.mission_start_date:
return iter([])
# Add 1 for inclusivity of both start and end dates
num_days = abs((rec.mission_end_date - rec.mission_start_date).days) + 1
return (rec.mission_start_date + timedelta(days=n) for n in range(num_days))
for rec in self:
# date range, including both start and end dates
dates = date_range_inclusive(rec)
# desired days to count
day_selection = (calendar.FRIDAY, calendar.SATURDAY)
rec.days_compensation = sum([dt.weekday() in day_selection for dt in dates])
The above code will assume that the date range is inclusive. Remove + 1
to make it not inclusive. It will set the days_compensation
field to 0 if no Fridays or Saturdays are included.
Note that there is no need to convert back and forth between data types since both the calendar days enumeration and weekday
function in datetime
evaluate to integers that can be compared.
Another thing to mind, is, according to https://www.odoo.com/documentation/8.0/reference/orm.html
computed fields are not stored by default, they are computed and returned when requested. Setting store=True will store them in the database and automatically enable searching
Therefore, you might want:
days_compensation = fields.Float(compute='get_compensation', compstring='Jours de récupération', help="Jours de récupération si la mission contient les jours de repos", required=True, readonly=True,
store=True)
Note the only update was store=True
Upvotes: 1
Reputation: 23089
I've played with your code. It seems to kinda work. It figures out what days of the week exist in a range of dates. The problem you're seeing occurs when there aren't both a Friday and a Saturday in your range of dates (note that you have a variable named 'mon' that is set by looking for the key 'Friday').
So it seems that your problem is just that you have to allow for the case where you don't have both these days of the week in the range of dates your provide as input. In that case, either or both of week.get('Friday') and week.get('Saturday') are not going to exist in your week map, and so mon and/or sat are going to be None, and you're going to have a problem.
To get your code to run, I added this below it:
class Rec:
def __init__(self, start, end):
self.mission_start_date = start
self.mission_end_date = end
self = [
Rec("2019-3-31", "2019-4-1")
]
get_compensation(self)
This lets me cause your code to process a pair of dates. If the range of dates I give here includes both a Friday and a Saturday, your code runs fine. Otherwise it barfs with exactly the error you're talking about.
If you change the lines:
mon = week.get('Friday')
sat = week.get('Saturday')
to:
mon = week.get('Friday') if 'Friday' in week else 0
sat = week.get('Saturday') if 'Saturday' in week else 0
then your code does not crash for any date ranges I tested it with. I don't know if it's computing the results you want, because you aren't holding onto or returning any of the results of your computations.
Upvotes: 0