AttributeError: 'datetime.date' object has no attribute 'hour' when creating an option - group by hour - odoo-8

I´m using odoo8 and want to create an option group by hour,
I know that I should not mess with core odoo code but it is just add to lines (I hope so), I check an "pivot by hour" module V10 and there are added the same two lines.
in addons\point_of_sale\report\pos_order_report_view.xml I added:
<filter string="Order Hour" context="{'group_by':'date:hour'}" help="Hour of order date"/>
and in server\openerp\modules.py in _read_group_process_groupby() method I added two lines:
def _read_group_process_groupby(self, gb, query, context):
split = gb.split(':')
field_type = self._fields[split[0]].type
gb_function = split[1] if len(split) == 2 else None
temporal = field_type in ('date', 'datetime')
tz_convert = field_type == 'datetime' and context.get('tz') in pytz.all_timezones
qualified_field = self._inherits_join_calc(self._table, split[0], query)
if temporal:
display_formats = {
'hour': 'HH:mm dd MMM yyyy', ###### added by me
'day': 'dd MMM yyyy',
'week': "'W'w YYYY",
'month': 'MMMM yyyy',
'quarter': 'QQQ yyyy',
'year': 'yyyy',
}
time_intervals = {
'hour': dateutil.relativedelta.relativedelta(hours=1), ###### added by me
'day': dateutil.relativedelta.relativedelta(days=1),
'week': datetime.timedelta(days=7),
'month': dateutil.relativedelta.relativedelta(months=1),
'quarter': dateutil.relativedelta.relativedelta(months=3),
'year': dateutil.relativedelta.relativedelta(years=1)
}
if tz_convert:
qualified_field = "timezone('%s', timezone('UTC',%s))" % (context.get('tz', 'UTC'),
qualified_field)
qualified_field = "date_trunc('%s', %s)" % (gb_function or 'month', qualified_field)
if field_type == 'boolean':
qualified_field = "coalesce(%s,false)" % qualified_field
return {
'field': split[0],
'groupby': gb,
'type': field_type,
'display_format': display_formats[gb_function or 'month'] if temporal else None,
'interval': time_intervals[gb_function or 'month'] if temporal else None,
'tz_convert': tz_convert,
'qualified_field': qualified_field
}
the whole traceback is the following:

Make sure that the types you pass to value are the same as the types you indexed on.
You pass the value that is the 'datetime.date' and this Return date object with the same year, month and day. Click Here
You can change it with to datetime.time()
Thanks

In models.py (with path: server/openerp) in _read_group_format_result method
.format_date(
need to be changed to
.format_datetime(

Related

daterangepicker max date_to value base from date_to value + 9hrs

Good day!
Is it possible to set max value of daterangepicker base on datefrom?.
What I want to accomplish is that when I select date_from, the max date value of date_to will be base from date_from + 9hours.
This is the library I use: https://www.daterangepicker.com/
This is the initial config:
// set reservation schedule
var max_duration = {{ $max_duration->value }};
var start = #if(Auth::user()->isAdmin()) moment() #else moment().add(3,'days') #endif;
var end = #if(Auth::user()->isAdmin()) moment().add(max_duration, 'hours') #else moment().add(3,'days').add(max_duration, 'hours') #endif;
$('#date_range').daterangepicker({
startDate: start,
endDate: end,
minDate: start,
applyButtonClasses: "btn-info",
cancelClass: "btn-danger",
alwaysShowCalendars: true,
timePicker: true,
"timePickerIncrement": 15,
}, reservation_schedule);
reservation_schedule(start, end);
function reservation_schedule(start, end) {
$('#date_range h6').html('<i class="fa fa-calendar-days"></i> ' + start.format('MMM D, YYYY hh:mm a') + ' - ' + end.format('MMM D, YYYY hh:mm a') + '<i class="fa fa-caret-down float-right"></i>');
$('#reservation_schedule').val(start.format('YYYY-MM-DD hh:mm a') + ' - ' + end.format('YYYY-MM-DD hh:mm a'));
}
Thanks in advance.

Calculating First Working Day adding holidays

I need to find the first working day of the month. Ideally it should be 01/MM/YYYY but the condition is that it should not be a Saturday or Sunday or a day from the List of Holidays.
List being:
ListOfHoliday
Name Day
Someday 01/01/2021
Someday 01/02/2021
Someday 31/03/2021
Someday 04/07/2021
Someday 25/12/2021
I was trying to use the below algo:
FWD = Text.concat(01, DateTime.CurrentMonthOfToday, DateTime.CurrentyearOfToday)
foreach(holiday in ListOfHoliday)
{
if (FWD == holiday)
{
DateTime.AddDays(ConvertTo.DateTime(FWD), 1)
if (ConvertTo.DateTime(FWD).DayOftheWeek == Saturday)
{
FWD=ConvertTo.Text(DateTime.AddDays(ConvertTo.DateTime(FWD), 2));
} else
{
if ((ConvertTo.DateTime(FWD).DayOftheWeek == Sunday))
{
FWD=ConvertTo.Text(DateTime.AddDays(ConvertTo.DateTime(FWD), 2));
}
}
}
}
But the result I get for the current month is 01/01/0001.
Here is the python code to find the first working day of a given month.
from datetime import datetime, timedelta
def working_day(temp,holid):
if temp.strftime('%A') == 'Saturday':
temp += timedelta(2)
return working_day(temp,holid)
elif temp.strftime('%A') == 'Sunday' or temp in holid:
temp += timedelta(1)
return working_day(temp,holid)
else:
return temp.strftime('%A')
date_format = "%d/%m/%Y"
holidays = ['01/01/2021','01/02/2021','31/03/2021','04/07/2021','25/12/2021']
holid = []
for day in holidays:
holid.append(datetime.strptime(day, date_format))
month = int(input('Enter the month')) # input should be 1,2,3....12
today ='01/'+str(month)+'/2021'
today = datetime.strptime(today, date_format)
print(working_day(today, holid))
output:
Enter the month 12
Wednesday

How to group and count missing values using linq

How do I go about counting missing values using linq. Basically I am counting occurrences within a particular month and I want the count to show as zero if there were no entries for that particular month.
However, currently if there are no entries for that month the array skips a month as shown at index 5 below. The reason I don't want this to happen is because I am plotting the results on a chart so the skipped dates are out of sync from index 5 onwards with the actual count.
Below is my linq query
var veterans = _db.Records
.Where(j => j.Requestor == "Veterans" && EF.Functions.DateDiffMonth(j.Request_Date, DateTime.Now) >= 0 && EF.Functions.DateDiffMonth(j.Request_Date, DateTime.Now) <= 24)
.GroupBy(g => new { g.Request_Date.Value.Year, g.Request_Date.Value.Month }).OrderBy(d => d.Key.Year).ThenBy(d => d.Key.Month)
.Select(group => new
{
Dates = group.Key,
Count = group.Count()
});
var veteransCount = veterans.Select(n => n.Count).ToArray();
You can create a helper function to generate the month+year enumeration you need:
public static IEnumerable<(int Year,int Month)> MonthsInYears(int fromYear, int fromMonth, int toYear, int toMonth) {
for (int year = fromYear; year <= toYear; ++year)
for (int month = (year == fromYear ? fromMonth : 1); month <= (year == toYear ? toMonth : 12); ++month)
yield return (year, month);
}
Then using this, you can create an enumeration of the period:
var veterans = _db.Records
.Where(j => j.Requestor == "Veterans" && EF.Functions.DateDiffMonth(j.Request_Date, DateTime.Now) >= 0 && EF.Functions.DateDiffMonth(j.Request_Date, DateTime.Now) <= 24)
.GroupBy(g => new { g.Request_Date.Value.Year, g.Request_Date.Value.Month }).OrderBy(d => d.Key.Year).ThenBy(d => d.Key.Month)
.Select(group => new {
YearMonth = group.Key,
Count = group.Count()
});
var minYearMonth = veterans.Select(v => v.YearMonth).First();
var maxYearMonth = veterans.Select(v => v.YearMonth).Last();
var monthsInYears = MonthsInYears(minYearMonth.Year, minYearMonth.Month, maxYearMonth.Year, maxYearMonth.Month);
Then you can GroupJoin (as a left join) to your database data:
var veteransCount = monthsInYears.GroupJoin(
veterans,
ym => new { ym.Year, ym.Month },
v => v.YearMonth,
(ym, sj) => sj.FirstOrDefault()?.Count ?? 0)
.ToArray();
Alternatively, since this is a specific case, you could create a Dictionary for your source data and lookup each enumeration value:
var veteransMap = veterans.ToDictionary(v => v.YearMonth, v => v.Count);
var veteransCount2 = monthsInYears.Select(ym => veteransMap.TryGetValue(new { ym.Year, ym.Month }, out var count) ? count : 0)
.ToArray();
NOTE: If you want the full beginning and ending years, you could just call the MonthsInYears method with 1 and 12 for the from and to months.

How to use date helper in CodeIgniter to find time conflict?

I have a database table
TABLE subject_loads
id (int)
subject_name (varchar)
time_start (time)
time_end (time)
time_diff (decimal)
When I save it on database, it will first check whether the time is not conflicting from the other time already inputed. If it's okay, then compute the time_start and time_end to give me a difference between the two.
Example, 7:30 AM - 8:30 AM is already in database, when i input 8:00 AM - 9:00 AM it will say "conflicting with the other time". Only I can input before 7:30 AM or after 8:30 AM that doesn't overlap from 7:30 AM - 8:30 AM.
Can someone help on how to do this?
First you need to check if overlapping values (compared to new value) already exist. You will do that with:
$query = $this->db->get_where('subject_loads', array('time_start >= ' => $time_start, 'time_end <= ' => $time_end));
if((int)$query->num_rows() > 0)
{
//similar values exist
}
else
{
//you are free to insert values
}
Second part of issue:
$hm1 = "2:12 AM";
$hm2 = "4:41 PM";
$e = conv($hm2) - conv($hm1);
echo $e;
function conv($time)
{
$expl_time = explode(' ', $time);
$t = explode(":", $expl_time[0]);
if ($expl_time[1] == 'PM' || $expl_time[1] == 'pm')
{
$t[0] += 12;
}
return ($t[0] + round($t[1]/60, 1, PHP_ROUND_HALF_UP));
}

Collection: filter by created_at by local time zone? (or CreatedAtStoreDate)

I have to filter a collection (invoice) by date to get all invoices of one month.
For example: the create_at date of one invoice (in database) is: 2014-04-30 22:27:30
If I filter the collection:
$dateFrom = '2014-04-01 00:00:00';
$dateTo = '2014-04-30 23:59:59';
$invoiceCollection->addAttributeToFilter('created_at', array(
'from' => $dateFrom,
'to' => $dateTo,
));
The invoice with this date will be in the collection.
There exists two kinds of dates:
$invoice->getCreatedAt()
And:
$invoice->getCreatedAtStoreDate()
In this case:
$invoice->getCreatedAt() = 2014-04-30 22:27:30 (UTC/GMT time)
$invoice->getCreatedAtStoreDate() = 2014-05-01 00:27:40 (local timezone)
Under Sales->Invoices "my" invoice will be collect under May. If I use
$invoiceCollection = Mage::getModel('sales/order_invoice')->getCollection();
the invoice is in "April".
So I have to filter my collection by CreatedAtStoreDate - but this is not a database-field.
My question:
How can I filter the order or invoice collection by CreatedAtStoreDate, so that the invoice or order with the date 2014-04-30 22:27:30 will be NOT in my April-Collection but in May?
Thanks for help.
You can use some GET param to define local offset, then add this offset to dates in filter. It will something like this (I didn't test it):
/**
* GET param which allow to set offset between local and server timezone. Server timezone is GMT.
* Examples: add ?gmt=2 in URL for set local time to GMT+2, ?gmt=-5 for GMT-5, etc.
*/
$gmt_offset = (int)Mage::app()->getRequest()->getParam('gmt');
$dateFrom = '2014-04-01 00:00:00';
$dateTo = '2014-04-30 23:59:59';
if($gmt_offset > -13 && $gmt_offset < 15 && $gmt_offset != 0){
$locale = Mage::app()->getLocale()->getLocaleCode();
$date_from = new Zend_Date(strtotime($dateFrom), Zend_Date::TIMESTAMP, $locale);
$date_to = new Zend_Date(strtotime($dateTo), Zend_Date::TIMESTAMP, $locale);
if($gmt_offset > 0){
$date_from->add($gmt_offset, Zend_Date::HOUR);
$date_to->add($gmt_offset, Zend_Date::HOUR);
}else{
$date_from->sub($gmt_offset, Zend_Date::HOUR);
$date_to->sub($gmt_offset, Zend_Date::HOUR);
}
$dateFrom = $date_from->get('YYYY-MM-dd HH:mm:ss');
$dateTo = $date_to->get('YYYY-MM-dd HH:mm:ss');
}
$invoiceCollection->addAttributeToFilter('created_at', array(
'from' => $dateFrom,
'to' => $dateTo,
));

Resources