Add days to a datetime and convert it to a date ? - Odoo V14 - date

i want to add 30 days to a datetime field and make my date field take this value as default.
I tried this, but don't work :/
from odoo import models, fields, api
from datetime import datetime
from dateutil.relativedelta import relativedelta
class crm_lead(models.Model):
_inherit = 'crm.lead'
date_deadline = fields.Datetime(string='Fermeture prévue')
#api.onchange('create_date')
def _onchange_enddate(self):
if self.create_date:
date_end = ( datetime.strptime(self.create_date, '%Y-%m-%d') + relativedelta(days =+ 30).strftime('%Y-%m-%d') )
self.date_deadline = date_end.date()
Thanks by advance !

The create_date is a magic field set in _create method. To use the creation date as a default value for the date_deadline field, you can use the default attribute and use the Date.today function to get the creation date.
Example:
date_deadline = fields.Datetime(default=lambda record: fields.Date.today() + relativedelta(days=30))

Does this work?:
from odoo import models, fields, api
from datetime import datetime, date, timedelta
class crm_lead(models.Model):
_inherit = 'crm.lead'
date_deadline = fields.Datetime(string='Fermeture prévue')
#api.onchange('create_date')
def _onchange_enddate(self):
if self.create_date:
date_end = ( date.today() + timedelta(30))
date_deadline = date_end
It gives the current date + 30 days.
It does not strip the datetime variable, so you might want to do that after.

Related

Convert using unixtimestamp to Date

I have a field in a dataframe that has a column with date like 1632838270314 as an example
I want to convert it to date like 'yyyy-MM-dd' I have this so far but it doesn't work:
date = df['createdOn'].cast(StringType())
df = df.withColumn('date_key',unix_timestamp(date),'yyyy-MM-dd').cast("date"))
createdOn is the field that derives the date_key
The method unix_timestamp() is for converting a timestamp or date string into the number seconds since 01-01-1970 ("epoch"). I understand that you want to do the opposite.
Your example value "1632838270314" seems to be milliseconds since epoch.
Here you can simply cast it after converting from milliseconds to seconds:
from pyspark.sql import functions as F
df = sql_context.createDataFrame([
Row(unix_in_ms=1632838270314),
])
(
df
.withColumn('timestamp_type', (F.col('unix_in_ms')/1e3).cast('timestamp'))
.withColumn('date_type', F.to_date('timestamp_type'))
.withColumn('string_type', F.col('date_type').cast('string'))
.withColumn('date_to_unix_in_s', F.unix_timestamp('string_type', 'yyyy-MM-dd'))
.show(truncate=False)
)
# Output
+-------------+-----------------------+----------+-----------+-----------------+
|unix_in_ms |timestamp_type |date_type |string_type|date_to_unix_in_s|
+-------------+-----------------------+----------+-----------+-----------------+
|1632838270314|2021-09-28 16:11:10.314|2021-09-28|2021-09-28 |1632780000 |
+-------------+-----------------------+----------+-----------+-----------------+
You can combine the conversion into a single command:
df.withColumn('date_key', F.to_date((F.col('unix_in_ms')/1e3).cast('timestamp')).cast('string'))

I want to compare from date and to date with date order using search orm in odoo

I want to compare from_date and to_date with date_order using search orm in odoo.
I just want to extract date alone because in date_order it is given date with date time. how to work with it ?
here is my code :
from_date = fields.Date(string="From", default="Today")
to_date = fields.Date(string="To")
def update_commission(self):
sale_br = self.env['sale.order']
sale_sr = sale_br.search([('date_order', '=', self.from_date)])
Modify your function like this:
def update_commission(self):
sale_br = self.env['sale.order']
sale_sr = sale_br.search([]).filtered(lambda sale: sale.date_order.date < self.from_date)
If you are working in odoo's past version like 10,11 than you need to convert this datetime into datetime object because when you call this field it will return date in string format so you need to do fields.Datetime.from_string(sale.date_order.date)

How to calculate 'Duration' between two 'DateTimes'

I have two DateTime objects:
import org.joda.time.{DateTime, Hours}
import scala.concurrent.duration._
val t1: DateTime = DateTime.now
val t2: DateTime = /* Some other time in the future */
I want to calculate the duration between the two:
val d: Duration = Duration(t2 - t1)
Obviously the code above does not work. I tried minus, but that requires a Duration, not a DateTime.
What is the easiest way to do this?
Joda-Time
Use org.joda.time.Duration constructor taking a pair of DateTime objects.
Duration d = new Duration( t1 , t2 ) ;
java.time
Use the static factory method on the java.time.Duration class.
Duration d = Duration.between( t1 , t2 ) ;
Agree with #stefanobaghino, try to use java.time which is available out of box since java 8. Regarding your case, check this:
Duration
public Duration(ReadableInstant start,
ReadableInstant end)
Creates a duration from the given interval endpoints.
Parameters:
start - interval start, null means now
end - interval end, null means now
Throws:
ArithmeticException - if the duration exceeds a 64 bit long
You was very close, hah
import scala.concurrent.duration._
val d = Duration(t2.getMillis - t1.getMillis, MILLISECONDS)

Python dateutil, check which value is given

I am parsing an excel document and get date time values...
I am using dateutil to convert it to python datetime values...
For example if incoming value is '2012' i need a way to understand that only year is given
or if value is '13:05' only hour-minute is given.
from dateutil.parser import *
def convertToDatetime(inValue):
#if inValue is '2012' i need a way to understand only year is given. Can i do this while parse method is used?
rVal = parse( inValue )
return rVal
How can i accomplish this?
----- EDIT ----
I can ask the question in this way too:
If only the year is given dateutil completes the day and month with today's values... But i need null values for month and day if only year is given...
This feature is yet to be implemented in the dateutil module. You can modify this snippet as per your requirement though.
from dateutil import parser
from datetime import datetime
import warnings
def double_parse(dt_str):
dflt_1 = datetime(1, 1, 1)
dflt_2 = datetime(2, 2, 2)
dt1 = parser.parse(dt_str, default=dflt_1)
dt2 = parser.parse(dt_str, default=dflt_2)
if dt2.year != dt1.year:
warnings.warn('Year is missing!', RuntimeWarning)
return dt1.replace(year=datetime.now().year)
return dt1
if __name__ == "__main__":
print(double_parse('2017-04-05'))
# 2017-04-05 00:00:00
print(double_parse('03:45 EST'))
# stderr: RuntimeWarning: Year is missing!
# 2017-01-01 03:45:00-05:00

using datetime object as an argument

I have been struggling to understand how to use datetime objects. I want to use datetime.date instances as keys in a dictionary. I then want to be able to return dates within specified ranges using datetime.delta.
My first conundrum is when I create an object to be entered into the dictionary.
class Work_day():
'''input a workday , date and hours worked'''
def __init__(self, date, hours, rate):
self.date = datetime.date()
self.hours = hours
self.rate = rate
I want self.date to be a datetime.date object but datetime.date takes 3 argument (year, month, day) so what is the correct syntax for the def_init_ argument 'date'?
Then I assume when I change how that is written in the Work_day class then I will have to modify my code when I create instances of it in the Timesheet class e.g. in add_work_day() method
class Timesheet():
'''Represent a collection of workdays'''
def __init__(self):
self.timesheet = {}
def add_work_day(self, date, hours,rate):
'''adds a record of a work day into the timesheet dictionary'''
day = Work_day(date, hours, rate)
if day.date in self.timesheet:
print("There is already an entry for this day. ")
else:
self.timesheet[day.date] = hours, rate
I've been researching the python docs and scouring books but I'm not getting it! Need some help.
I also have a method that prints a range of the workdays in the timesheet. I made it work when I subbed the date key for a simple int. here it is (in ''' ''') with a shonky attempt at a datetime delta underneath
def show_days(self):
'''shows a user defined range of dates and the total pay for that period'''
pp = pprint.PrettyPrinter()
date_from = input("From date: ")
date_to = input("To date: ")
t = self.timesheet
total = 0
'''for dates in range(date_from, date_to + 1):
if dates in t:
total += self.sum_day(dates)
pp.pprint((dates, t[dates)])
print("Total £", total)'''
date = date_start = datetime.date(date_from)
date_end = datetime.date(date_to)
while date <= date_end:
if date in t:
print(date, t[dates])
date += datetime.timedelta(days=1)
I hope someone can find the patience to talk me through this. Cheers.
If you assign the date with self.date = datetime.date(*date), then you can create a Work_day by passing a (year,month,day) tuple:
day = Work_day((2013,5,31), 8.0, 8.25)
Alternatively, if you want the input to be a date string, use datetime.strptime, an appropriate formatting string, and the date() method to get a date object:
self.date = datetime.datetime.strptime(date,'%m/%d/%Y').date()
...
date = Work_day('5/31/2013', 8.0, 8.25)
Finally, you could just pass a date object:
day = Work_day(datetime.date(2013,5,31), 8.0, 8.25)
...
self.date = date
The Timesheet class should work after any of these changes. show_days still needs some work, but I'll leave that as an exercise. Hint: Parse the input dates with strptime.