formdata: store datetimes with timezone (#52057) #1122

Merged
fpeters merged 1 commits from wip/52057-timezone into main 2024-02-12 15:28:35 +01:00
30 changed files with 302 additions and 267 deletions

View File

@ -4,6 +4,7 @@ import os
import pytest
from django.utils.html import escape
from django.utils.timezone import make_aware
from webtest import Upload
from wcs import fields
@ -103,7 +104,7 @@ def test_tests_page_creation_from_formdata(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'abcdefg'
formdata.user_id = user.id
formdata.store()
@ -122,7 +123,7 @@ def test_tests_page_creation_from_formdata(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2022, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2022, 1, 1, 0, 0))
formdata.data['1'] = 'hijklmn'
formdata.backoffice_submission = True
formdata.store()
@ -167,7 +168,7 @@ def test_tests_import_export(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'a'
formdata.user_id = user.id
formdata.store()
@ -224,7 +225,7 @@ def test_tests_status_page(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'This is a test'
formdata.user_id = user.id
formdata.store()
@ -264,7 +265,7 @@ def test_tests_status_page_block_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = {'data': [{'1': 'foo'}]}
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -288,7 +289,7 @@ def test_tests_status_page_image_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
upload = PicklableUpload('test.jpeg', 'image/jpeg')
with open(os.path.join(os.path.dirname(__file__), '..', 'image-with-gps-data.jpeg'), 'rb') as jpg:
@ -325,7 +326,7 @@ def test_tests_edit(pub):
formdef.store()
formdata = formdef.data_class()()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.user_id = user.id
formdata.data = {'1': 'xxx'}
formdata.store()
@ -375,7 +376,7 @@ def test_tests_edit_data(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'test 1'
formdata.data['3'] = 'test 2'
formdata.user_id = user.id
@ -434,7 +435,7 @@ def test_tests_edit_data_mark_as_failing(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = '12345'
formdata.store()
@ -516,7 +517,7 @@ def test_tests_edit_data_mark_as_failing_hidden_error(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['0'] = 'not-digits'
formdata.data['1'] = 'also-not-digits'
formdata.store()
@ -548,7 +549,7 @@ def test_tests_edit_data_mark_as_failing_required_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.store()
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -599,7 +600,7 @@ def test_tests_edit_data_is_in_backoffice(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = '12345'
formdata.store()
@ -690,7 +691,7 @@ def test_tests_manual_run(pub):
# create test
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'a'
formdata.user_id = user.id
formdata.store()
@ -787,7 +788,7 @@ def test_tests_result_recorded_errors(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.store()
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -845,7 +846,7 @@ def test_tests_duplicate(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'abcdefg'
formdata.user_id = user.id
formdata.store()
@ -885,7 +886,7 @@ def test_tests_page_with_empty_map_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = None
formdata.store()
@ -970,12 +971,12 @@ def test_tests_exclude_self(pub):
submitted_formdata = formdef.data_class()()
submitted_formdata.just_created()
submitted_formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
submitted_formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
submitted_formdata.store()
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/tests/new')

View File

@ -10,6 +10,7 @@ import zipfile
import pytest
from django.utils.encoding import force_bytes
from django.utils.timezone import localtime, make_aware
from quixote import get_publisher
from webtest import Upload
@ -979,15 +980,13 @@ def test_api_list_formdata(pub, local_user):
if i % 7 == 0:
formdata.backoffice_submission = True
formdata.submission_channel = 'mail'
formdata.receipt_time = (
datetime.datetime(2018, 1, 2, 3, 4) + datetime.timedelta(hours=i)
).timetuple()
formdata.evolution[0].time = (
formdata.receipt_time = make_aware(datetime.datetime(2018, 1, 2, 3, 4) + datetime.timedelta(hours=i))
formdata.evolution[0].time = make_aware(
datetime.datetime(2019, 1, 2, 3, 4) + datetime.timedelta(hours=i)
).timetuple()
formdata.evolution[-1].time = (
)
formdata.evolution[-1].time = make_aware(
datetime.datetime(2020, 1, 2, 3, 4) + datetime.timedelta(hours=i)
).timetuple()
)
formdata._store_all_evolution = True
formdata.store()
# a draft by user
@ -2561,7 +2560,7 @@ def test_api_anonymized_formdata(pub, local_user, admin_user):
else:
evo = Evolution(formdata=formdata)
evo.who = admin_user.id
evo.time = time.localtime()
evo.time = localtime()
evo.status = 'wf-%s' % 'st2'
formdata.evolution.append(evo)
formdata.status = evo.status

View File

@ -10,6 +10,7 @@ from functools import partial
import pytest
import responses
from django.utils.encoding import force_str
from django.utils.timezone import localtime
from quixote import get_publisher
from wcs import fields, qommon
@ -163,7 +164,7 @@ def test_formdef_list(pub):
formdata = formdef.data_class()()
formdata.data = {}
formdata.just_created()
formdata.receipt_time = (datetime.datetime.now() - datetime.timedelta(days=days)).timetuple()
formdata.receipt_time = localtime() - datetime.timedelta(days=days)
formdata.store()
resp = get_app(pub).get(sign_uri('/api/formdefs/?include-count=on'))
@ -1222,6 +1223,8 @@ def test_formdef_import_export_unnamed_block(pub, admin_user):
formdata_export = formdata.get_json_export_dict(include_unnamed_fields=True, include_evolution=False)
del formdata_export['receipt_time']
del formdata_export['last_update_time']
del formdata_export['workflow']['real_status']['first_arrival_datetime']
del formdata_export['workflow']['real_status']['latest_arrival_datetime']
formdef.data_class().wipe()
app = login(get_app(pub))

View File

@ -3,6 +3,7 @@ import json
import os
import pytest
from django.utils.timezone import make_aware
from wcs import fields
from wcs.backoffice.management import format_time
@ -313,7 +314,7 @@ def test_statistics_forms_count(pub):
for i in range(20):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
# "Web" channel has three equivalent values
if i == 0:
formdata.submission_channel = 'web'
@ -327,14 +328,14 @@ def test_statistics_forms_count(pub):
for i in range(30):
formdata = formdef2.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 3, 1, 2, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 3, 1, 2, 0))
formdata.backoffice_submission = bool(i % 3)
formdata.submission_channel = 'mail'
formdata.store()
# draft should not be counted
formdata = formdef.data_class()()
formdata.receipt_time = datetime.datetime(2021, 3, 1, 2, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 3, 1, 2, 0))
formdata.status = 'draft'
formdata.store()
@ -414,7 +415,7 @@ def test_statistics_forms_count_subfilters(pub, formdef):
formdata.data['3_display'] = 'Foo' if i % 2 else 'Bar, Baz'
formdata.data['4'] = {'data': [{'2': ['foo', 'bar'], '2_display': 'Foo, Bar'}]}
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.store()
url = '/api/statistics/forms/count/?form=%s&time_interval=year' % formdef.url_name
@ -593,7 +594,7 @@ def test_statistics_forms_count_subfilters_empty_block_items_field(pub, formdef)
formdata = formdef.data_class()()
formdata.data['4'] = {'data': [{'1': 'a', '1_display': 'B'}]}
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.store()
resp = get_app(pub).get(sign_uri('/api/statistics/forms/count/?form=%s' % formdef.url_name))
@ -619,7 +620,7 @@ def test_statistics_forms_count_subfilters_empty_item_field_no_datasource(pub, f
formdata.just_created()
formdata.data['10'] = 'extra-option'
formdata.data['10_display'] = 'Extra option'
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.store()
resp = get_app(pub).get(sign_uri('/api/statistics/forms/count/?form=%s' % formdef.url_name))
@ -647,7 +648,7 @@ def test_statistics_forms_count_subfilters_query(pub, formdef):
formdata.data['3'] = ['baz']
formdata.data['4'] = {'data': [{'1': False, '2': ['foo', 'bar'], '2_display': 'Foo, Bar'}]}
formdata.jump_status('2')
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.store()
# query all formdata
@ -769,7 +770,7 @@ def test_statistics_forms_count_subfilters_query_same_varname(pub, formdef):
for i in range(5):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
if i == 0:
formdata.data['1'] = 'foo'
if i == 1:
@ -803,7 +804,7 @@ def test_statistics_forms_count_subfilters_query_integer_items(pub, formdef):
formdata.data['3'] = ['1', '2']
else:
formdata.data['3'] = ['1']
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.store()
url = '/api/statistics/forms/count/?form=%s' % formdef.url_name
@ -819,7 +820,7 @@ def test_statistics_forms_count_group_by(pub, formdef, anonymise):
for i in range(20):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
if i % 3:
formdata.data['1'] = True
formdata.data['2'] = 'foo'
@ -855,7 +856,7 @@ def test_statistics_forms_count_group_by(pub, formdef, anonymise):
formdata.submission_channel = 'mail'
formdata.backoffice_submission = bool(i % 3)
else:
formdata.receipt_time = datetime.datetime(2021, 3, 1, 2, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 3, 1, 2, 0))
formdata.store()
if anonymise:
formdata.anonymise()
@ -1017,7 +1018,7 @@ def test_statistics_forms_count_group_by_same_varname(pub, formdef):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'foo'
formdata.data['2'] = 'bar'
formdata.store()
@ -1036,7 +1037,7 @@ def test_statistics_forms_count_group_by_same_varname(pub, formdef):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['2'] = 'foo'
formdata.store()
@ -1052,7 +1053,7 @@ def test_statistics_forms_count_group_by_form(pub):
for i in range(10):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2022, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2022, 1, 1, 0, 0))
formdata.store()
formdef = FormDef()
@ -1062,7 +1063,7 @@ def test_statistics_forms_count_group_by_form(pub):
for i in range(5):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.store()
resp = get_app(pub).get(sign_uri('/api/statistics/forms/count/'))
@ -1095,7 +1096,7 @@ def test_statistics_forms_count_months_to_show(pub, formdef):
formdata.data['2'] = 'foo' if i % 2 else 'baz'
formdata.data['2_display'] = 'Foo' if i % 2 else 'Baz'
formdata.just_created()
formdata.receipt_time = datetime.datetime(2022 + i // 12, i % 12 + 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2022 + i // 12, i % 12 + 1, 1, 0, 0))
formdata.store()
url = '/api/statistics/forms/count/'
@ -1140,7 +1141,7 @@ def test_statistics_cards_count(pub):
for _i in range(20):
carddata = carddef.data_class()()
carddata.just_created()
carddata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
carddata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
carddata.store()
# apply (required) card filter
@ -1399,8 +1400,8 @@ def test_statistics_resolution_time_median(pub, freezer):
resp = get_app(pub).get(sign_uri('/api/statistics/resolution-time/?form=test'))
assert get_humanized_duration_serie(resp.json) == [
'1 day(s) and 0 hour(s)', # min
'89 day(s) and 23 hour(s)', # max
'13 day(s) and 23 hour(s)', # mean
'90 day(s) and 0 hour(s)', # max
'14 day(s) and 0 hour(s)', # mean
'5 day(s) and 0 hour(s)', # median
]
@ -1511,7 +1512,7 @@ def test_statistics_multiple_forms_count(pub, formdef):
formdata.data['3'] = ['foo']
formdata.data['3_display'] = 'Foo'
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.store()
for _i in range(30):
@ -1522,7 +1523,7 @@ def test_statistics_multiple_forms_count(pub, formdef):
formdata.data['3_display'] = 'Bar, Baz'
formdata.data['4'] = {'data': [{'1': True}]}
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 3, 1, 2, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 3, 1, 2, 0))
formdata.jump_status('2')
formdata.store()
@ -1622,14 +1623,14 @@ def test_statistics_multiple_forms_count_different_ids(pub):
formdata.data['1'] = 'foo'
formdata.data['1_display'] = 'Foo'
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.store()
formdata = formdef2.data_class()()
formdata.data['2'] = 'baz'
formdata.data['2_display'] = 'Baz'
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 3, 1, 2, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 3, 1, 2, 0))
formdata.store()
url = '/api/statistics/forms/count/?form=%s&form=%s' % (formdef1.url_name, formdef2.url_name)
@ -1664,7 +1665,7 @@ def test_statistics_multiple_forms_count_subfilters(pub, formdef):
formdata.data['2'] = 'foo'
formdata.data['2_display'] = 'Foo'
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.jump_status('2')
formdata.store()
@ -1673,7 +1674,7 @@ def test_statistics_multiple_forms_count_subfilters(pub, formdef):
formdata.data['2'] = 'baz'
formdata.data['2_display'] = 'Baz'
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 3, 1, 2, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 3, 1, 2, 0))
formdata.store()
resp = get_app(pub).get(

View File

@ -3,6 +3,7 @@ import os
from functools import partial
import pytest
from django.utils.timezone import make_aware
from quixote import get_publisher
from wcs import fields
@ -377,7 +378,7 @@ def test_user_forms(pub, local_user, access):
formdata = formdef.data_class()()
formdata.user_id = local_user.id
formdata.status = 'draft'
formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2015, 1, 1))
formdata.store()
resp = get_app(pub).get(sign_uri('/api/user/forms', user=local_user))
@ -399,7 +400,7 @@ def test_user_forms(pub, local_user, access):
formdata.data = {'0': 'foo@localhost', '1': 'xyy'}
formdata.user_id = local_user.id
formdata.just_created()
formdata.receipt_time = (datetime.datetime.now() + datetime.timedelta(days=1)).timetuple()
formdata.receipt_time = make_aware(datetime.datetime.now() + datetime.timedelta(days=1))
formdata.jump_status('new')
formdata.store()
@ -408,9 +409,9 @@ def test_user_forms(pub, local_user, access):
resp2 = get_app(pub).get(sign_uri('/api/user/forms?sort=desc', user=local_user))
assert len(resp2.json['data']) == 4
assert resp2.json['data'][0] == resp.json['data'][3]
assert resp2.json['data'][1] == resp.json['data'][0]
assert resp2.json['data'][1] == resp.json['data'][2]
assert resp2.json['data'][2] == resp.json['data'][1]
assert resp2.json['data'][3] == resp.json['data'][2]
assert resp2.json['data'][3] == resp.json['data'][0]

test_user_forms, le test qui échouait parfois, était tout foireux, il récupérait une liste de demandes, puis la même en ordre inversé, et regardait si les demandes (0, 1, 2, 3) correspondaient bien aux demandes (3, 0, 1, 2). Ça n'avait pas de sens mais c'était la plupart du temps le résultat parce que les demandes 0 1 et 2 étaient créées avec le même timestamp. Maintenant qu'on a des timestamps plus précis, l'ordre (3, 2, 1, 0) qui aurait dû être vérifié depuis le début devient systématique.

test_user_forms, le test qui échouait parfois, était tout foireux, il récupérait une liste de demandes, puis la même en ordre inversé, et regardait si les demandes (0, 1, 2, 3) correspondaient bien aux demandes (3, 0, 1, 2). Ça n'avait pas de sens mais c'était la plupart du temps le résultat parce que les demandes 0 1 et 2 étaient créées avec le même timestamp. Maintenant qu'on a des timestamps plus précis, l'ordre (3, 2, 1, 0) qui aurait dû être vérifié depuis le début devient systématique.
# check there is no access with roles-limited API users
role = pub.role_class(name='test')
@ -443,7 +444,7 @@ def test_user_forms_limit_offset(pub, local_user):
formdata.data = {'0': 'foo@localhost', '1': str(i)}
formdata.user_id = local_user.id
formdata.just_created()
formdata.receipt_time = (datetime.datetime.now() + datetime.timedelta(days=i)).timetuple()
formdata.receipt_time = make_aware(datetime.datetime.now() + datetime.timedelta(days=i))
formdata.jump_status('new')
formdata.store()
@ -452,7 +453,7 @@ def test_user_forms_limit_offset(pub, local_user):
formdata.data = {'0': 'foo@localhost', '1': str(i)}
formdata.user_id = local_user.id
formdata.status = 'draft'
formdata.receipt_time = (datetime.datetime.now() - datetime.timedelta(days=i)).timetuple()
formdata.receipt_time = make_aware(datetime.datetime.now() - datetime.timedelta(days=i))
formdata.store()
resp = get_app(pub).get(sign_uri('/api/users/%s/forms' % local_user.id))
@ -772,7 +773,7 @@ def test_user_drafts(pub, local_user):
formdata.user_id = local_user.id
formdata.page_no = 1
formdata.status = 'draft'
formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2015, 1, 1))
formdata.store()
resp = get_app(pub).get(sign_uri('/api/user/drafts', user=local_user))

View File

@ -9,6 +9,7 @@ import zipfile
import pytest
import responses
from django.utils.timezone import make_aware
from webtest import Upload
import wcs.qommon.storage as st
@ -132,7 +133,7 @@ def create_environment(pub, set_receiver=True):
for i in range(50):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2015, 1, 1, 0, i).timetuple()
formdata.receipt_time = datetime.datetime(2015, 1, 1, 0, i)
formdata.data = {'1': 'FOO BAR %d' % i}
if i % 4 == 0:
formdata.data[formdef.fields[1].id] = 'foo'
@ -170,7 +171,7 @@ def create_environment(pub, set_receiver=True):
for i in range(20):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2014, 1, 1).timetuple()
formdata.receipt_time = datetime.datetime(2014, 1, 1)
formdata.jump_status('new')
formdata.store()
@ -1259,9 +1260,9 @@ def test_backoffice_multi_actions_interactive(pub):
for i in range(10):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2015, 1, 1, 0, i).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2015, 1, 1, 0, i))
formdata.jump_status('new')
formdata.evolution[-1].time = datetime.datetime(2015, 1, 1, 0, i).timetuple()
formdata.evolution[-1].time = make_aware(datetime.datetime(2015, 1, 1, 0, i))
formdata.store()
app = login(get_app(pub))
@ -3231,7 +3232,7 @@ def test_global_listing(pub):
last_update_time = formdef.data_class().select(lambda x: not x.is_draft())[0].last_update_time
# check created and last modified columns
assert '>2014-01-01 00:00<' in resp.text
assert time.strftime('>%Y-%m-%d', last_update_time) in resp.text
assert f'>{last_update_time.strftime("%Y-%m-%d")}' in resp.text
# check digest is included
formdata = formdef.data_class().get(

View File

@ -8,6 +8,7 @@ import xml.etree.ElementTree as ET
import zipfile
import pytest
from django.utils.timezone import make_aware
from wcs import fields
from wcs.blocks import BlockDef
@ -75,7 +76,7 @@ def test_backoffice_csv(pub):
formdef.data_class().wipe()
for i in range(3):
formdata = formdef.data_class()()
formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2015, 1, 1))
formdata.data = {'1': 'FOO BAR %d' % i}
if i == 0:
formdata.data['2'] = 'foo'
@ -247,7 +248,7 @@ def test_backoffice_export_long_listings(pub, threshold):
formdef.data_class().wipe()
for i in range(2):
formdata = formdef.data_class()()
formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2015, 1, 1))
formdata.data = {'1': 'BAZ BAZ %d' % i}
formdata.jump_status('new')
formdata.store()
@ -264,8 +265,8 @@ def test_backoffice_export_long_listings(pub, threshold):
resp_lines = resp.text.splitlines()
assert resp_lines[0] == '"Number","Created","Last Modified","User Label","1st field","Status"'
assert len(resp_lines) == 3
assert resp_lines[1].split(',')[1].startswith('"' + time.strftime('%Y-%m-%d', formdata.receipt_time))
assert resp_lines[1].split(',')[2].startswith('"' + time.strftime('%Y-%m-%d', formdata.last_update_time))
assert resp_lines[1].split(',')[1].startswith('"' + formdata.receipt_time.strftime('%Y-%m-%d'))
assert resp_lines[1].split(',')[2].startswith('"' + formdata.last_update_time.strftime('%Y-%m-%d'))
resp = app.get('/backoffice/management/form-title/')
resp = resp.click('Export a Spreadsheet')
@ -1117,7 +1118,7 @@ def test_backoffice_header_line(pub):
formdef.data_class().wipe()
for i in range(3):
formdata = formdef.data_class()()
formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2015, 1, 1))
formdata.data = {'1': 'FOO BAR %d' % i}
formdata.jump_status('new')
formdata.store()

View File

@ -1,10 +1,11 @@
import datetime
import io
import json
import os
import re
import time
import pytest
from django.utils.timezone import localtime
from pyquery import PyQuery
from wcs import fields
@ -821,7 +822,7 @@ def test_inspect_page_actions_traces(pub):
assert formdata.status == 'wf-accepted'
# change receipt time to get global timeout to run
formdata.receipt_time = time.localtime(time.time() - 3 * 86400)
formdata.receipt_time = localtime() - datetime.timedelta(days=3)
formdata.store()
pub.apply_global_action_timeouts()
formdata.refresh_from_storage()

View File

@ -3,6 +3,7 @@ import os
import re
import pytest
from django.utils.timezone import make_aware
from wcs import fields
from wcs.blocks import BlockDef
@ -64,9 +65,9 @@ def test_backoffice_listing_order(pub):
formdata.jump_status('new')
formdata.store()
ids.append(formdata.id)
formdata.receipt_time = datetime.datetime(2015, 1, 1, 10, i).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2015, 1, 1, 10, i))
# ordered with odd-numbered ids then even-numbered ids
formdata.evolution[-1].time = datetime.datetime(2015, 2, 1, 10 + i % 2, i).timetuple()
formdata.evolution[-1].time = make_aware(datetime.datetime(2015, 2, 1, 10 + i % 2, i))
formdata.store()
inversed_receipt_time_order = list(reversed([str(x) for x in sorted(ids)]))
@ -142,7 +143,7 @@ def test_backoffice_criticality_in_formdef_listing_order(pub):
formdata.data = {}
formdata.just_created()
formdata.jump_status('new')
formdata.receipt_time = datetime.datetime(2015, 1, 1, 10, i).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2015, 1, 1, 10, i))
if i < 8:
if i % 3 == 0:
formdata.set_criticality_level(1)

View File

@ -1,10 +1,10 @@
import datetime
import os
import re
import time
import pytest
import responses
from django.utils.timezone import localtime, make_aware
from wcs import fields
from wcs.carddef import CardDef
@ -213,7 +213,7 @@ def test_backoffice_submission_with_tracking_code(pub):
assert formdata.tracking_code in resp.text
# check access at a later time
formdata.receipt_time = time.localtime(time.time() - 3600)
formdata.receipt_time = localtime() - datetime.timedelta(hours=1)
formdata.store()
resp = app.get(formdata_location)
assert formdata.tracking_code not in resp.text
@ -977,7 +977,7 @@ def test_backoffice_submission_sections(pub):
formdata.data = {}
formdata.status = 'draft'
formdata.backoffice_submission = True
formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2015, 1, 1))
formdata.store()
resp = app.get('/backoffice/submission/')
@ -1016,7 +1016,7 @@ def test_backoffice_submission_drafts_order(pub):
formdata.data = {}
formdata.status = 'draft'
formdata.backoffice_submission = True
formdata.receipt_time = datetime.datetime(2023, 11, 20 - i).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2023, 11, 20 - i))
formdata.store()
formdata_ids.append(formdata.id)

View File

@ -3,6 +3,7 @@ import time
from unittest import mock
import pytest
from django.utils.timezone import make_aware
from webtest import Upload
from wcs import fields
@ -386,7 +387,7 @@ def test_form_max_drafts(pub):
# create another draft, not linked to user, to check it's not deleted
another_draft = formdef.data_class()()
another_draft.status = 'draft'
another_draft.receipt_time = datetime.datetime(2023, 11, 23, 0, 0).timetuple()
another_draft.receipt_time = make_aware(datetime.datetime(2023, 11, 23, 0, 0))
another_draft.store()
drafts = []
@ -394,7 +395,7 @@ def test_form_max_drafts(pub):
draft = formdef.data_class()()
draft.user_id = user.id
draft.status = 'draft'
draft.receipt_time = datetime.datetime(2023, 11, 23, 0, i).timetuple()
draft.receipt_time = make_aware(datetime.datetime(2023, 11, 23, 0, i))
draft.store()
drafts.append(draft)

View File

@ -1357,7 +1357,7 @@ def test_api_formdata_at(pub, user, access, role):
evo.add_part(part)
evo = Evolution(formdata=formdata)
evo.time = time.localtime()
evo.time = localtime()
evo.status = formdata.status
part = ContentSnapshotPart(formdata=formdata, old_data={'0': 'bar', 'bo1': 'foo'})
part.new_data = {'0': 'baz', 'bo1': 'foo'}
@ -1366,7 +1366,7 @@ def test_api_formdata_at(pub, user, access, role):
formdata.evolution.append(evo)
evo = Evolution(formdata=formdata)
evo.time = time.localtime()
evo.time = localtime()
evo.status = formdata.status
part = ContentSnapshotPart(formdata=formdata, old_data={'0': 'baz', 'bo1': 'foo'})
part.new_data = {'0': 'foooo', '1': 'unknown', 'bo1': 'foo'}
@ -1375,7 +1375,7 @@ def test_api_formdata_at(pub, user, access, role):
formdata.evolution.append(evo)
evo = Evolution(formdata=formdata)
evo.time = time.localtime()
evo.time = localtime()
evo.status = formdata.status
part = ContentSnapshotPart(formdata=formdata, old_data={'0': 'foooo', '1': 'unknown', 'bo1': 'foo'})
part.new_data = {'0': 'fooo', 'bo1': 'foo'}

View File

@ -9,6 +9,7 @@ from unittest import mock
import pytest
from django.utils import formats
from django.utils.timezone import localtime, make_aware
from quixote import get_publisher, get_request
from quixote.http_request import Upload
@ -392,7 +393,7 @@ def test_get_last_update_time(pub, formdef):
time.sleep(1)
evo = Evolution(formdata=formdata)
evo.time = time.localtime()
evo.time = localtime()
evo.status = formdata.status
evo.comment = 'hello world'
formdata.evolution.append(evo)
@ -442,13 +443,13 @@ def test_clean_drafts(pub):
d = formdef.data_class()()
d.status = 'draft'
d.receipt_time = time.localtime()
d.receipt_time = localtime()
d.store()
d_id1 = d.id
d = formdef.data_class()()
d.status = 'draft'
d.receipt_time = time.localtime(0) # epoch, 1970-01-01
d.receipt_time = make_aware(datetime.datetime(1970, 1, 1))
d.store()
assert formdef.data_class().count() == 2
@ -460,7 +461,7 @@ def test_clean_drafts(pub):
d = formdef.data_class()()
d.status = 'draft'
d.receipt_time = time.localtime(time.time() - 86400 * 5)
d.receipt_time = localtime() - datetime.timedelta(days=5)
d.store()
clean_drafts(pub)
assert formdef.data_class().count() == 2
@ -575,9 +576,9 @@ def test_get_json_export_dict_evolution(pub, local_user):
d = formdef.data_class()()
d.status = 'wf-%s' % st_new.id
d.user_id = local_user.id
d.receipt_time = time.localtime()
d.receipt_time = localtime()
evo = Evolution(formdata=d)
evo.time = time.localtime()
evo.time = localtime()
evo.status = 'wf-%s' % st_new.id
evo.who = '_submitter'
d.evolution = [evo]
@ -587,7 +588,7 @@ def test_get_json_export_dict_evolution(pub, local_user):
evo.add_part(JournalAssignationErrorPart('summary', 'label'))
d.store()
evo = Evolution(formdata=d)
evo.time = time.localtime()
evo.time = localtime()
evo.status = 'wf-%s' % st_finished.id
evo.who = '_submitter'
d.evolution.append(evo)
@ -731,25 +732,25 @@ def test_evolution_get_status(pub):
d.evolution = []
evo = Evolution(formdata=d)
evo.time = time.localtime()
evo.time = localtime()
evo.status = 'wf-%s' % st_new.id
d.evolution.append(evo)
evo = Evolution(formdata=d)
evo.time = time.localtime()
evo.time = localtime()
d.evolution.append(evo)
evo = Evolution(formdata=d)
evo.time = time.localtime()
evo.time = localtime()
d.evolution.append(evo)
evo = Evolution(formdata=d)
evo.time = time.localtime()
evo.time = localtime()
evo.status = 'wf-%s' % st_finished.id
d.evolution.append(evo)
evo = Evolution(formdata=d)
evo.time = time.localtime()
evo.time = localtime()
d.evolution.append(evo)
d.store()
@ -833,9 +834,9 @@ def test_lazy_formdata(pub, variable_test_data):
formdef = FormDef.select()[0]
formdata = formdef.data_class().select()[0]
lazy_formdata = LazyFormData(formdata)
assert lazy_formdata.receipt_date == time.strftime('%Y-%m-%d', formdata.receipt_time)
assert lazy_formdata.receipt_time == formats.time_format(datetime.datetime(*formdata.receipt_time[:6]))
assert lazy_formdata.last_update_datetime.timetuple()[:6] == formdata.last_update_time[:6]
assert lazy_formdata.receipt_date == formdata.receipt_time.strftime('%Y-%m-%d')
assert lazy_formdata.receipt_time == formats.time_format(formdata.receipt_time)
assert lazy_formdata.last_update_datetime.timetuple()[:6] == formdata.last_update_time.timetuple()[:6]
assert lazy_formdata.internal_id == formdata.id
assert lazy_formdata.name == 'foobarlazy'
assert lazy_formdata.display_name == 'foobarlazy #%s' % formdata.get_display_id()
@ -5369,7 +5370,7 @@ def test_get_visible_status(pub, local_user):
# create evolution [new, empty, finished, empty]
for status in (st_new, None, st_finished, None):
evo = Evolution(formdata=formdata)
evo.time = time.localtime()
evo.time = localtime()
if status:
evo.status = 'wf-%s' % status.id
formdata.evolution.append(evo)
@ -5630,7 +5631,7 @@ def test_get_status_datetime(pub, freezer):
freezer.move_to(datetime.datetime(2023, 10, 31, 12, 0))
evo = Evolution(formdata=formdata)
evo.time = time.localtime()
evo.time = localtime()
formdata.evolution.append(evo)
assert formdata.get_status_datetime(status=st_next) == formdata.evolution[1].time
assert formdata.get_status_datetime(status=st_next, latest=True) == formdata.evolution[1].time

View File

@ -10,6 +10,7 @@ import zipfile
import psycopg2
import pytest
from django.utils.timezone import localtime, make_aware
from django.utils.timezone import now as tz_now
import wcs.sql_criterias as st
@ -390,7 +391,7 @@ def test_sql_evolution(formdef):
assert len(formdata.evolution) == 1
evo = Evolution(formdata=formdata)
evo.time = time.localtime()
evo.time = localtime()
evo.status = formdata.status
evo.comment = 'hello world'
formdata.evolution.append(evo)
@ -412,7 +413,7 @@ def test_sql_evolution_change(formdef):
assert len(formdata.evolution) == 1
evo = Evolution(formdata=formdata)
evo.time = time.localtime()
evo.time = localtime()
evo.status = formdata.status
evo.comment = 'hello world'
formdata.evolution.append(evo)
@ -441,7 +442,7 @@ def test_sql_multiple_evolutions(formdef):
formdata = data_class.get(id)
evo = Evolution(formdata=formdata)
evo.time = time.localtime()
evo.time = localtime()
evo.status = formdata.status
evo.comment = 'hello world %d' % i
formdata.evolution.append(evo)
@ -930,24 +931,19 @@ def test_sql_table_select_datetime(pub):
data_class = test_formdef.data_class(mode='sql')
assert data_class.count() == 0
d = datetime.datetime(2014, 1, 1)
d = make_aware(datetime.datetime(2014, 1, 1))
for i in range(50):
t = data_class()
t.receipt_time = (d + datetime.timedelta(days=i)).timetuple()
t.receipt_time = d + datetime.timedelta(days=i)
t.store()
assert data_class.count() == 50
assert len(data_class.select()) == 50
assert len(data_class.select(lambda x: x.receipt_time == d.timetuple())) == 1
assert len(data_class.select([st.Equal('receipt_time', d.timetuple())])) == 1
assert (
len(data_class.select([st.Less('receipt_time', (d + datetime.timedelta(days=20)).timetuple())])) == 20
)
assert (
len(data_class.select([st.Greater('receipt_time', (d + datetime.timedelta(days=20)).timetuple())]))
== 29
)
assert len(data_class.select(lambda x: x.receipt_time == d)) == 1
assert len(data_class.select([st.Equal('receipt_time', d)])) == 1
assert len(data_class.select([st.Less('receipt_time', d + datetime.timedelta(days=20))])) == 20
assert len(data_class.select([st.Greater('receipt_time', d + datetime.timedelta(days=20))])) == 29
assert len(data_class.select([st.Equal('receipt_time', datetime.date(1900, 1, 1).timetuple())])) == 0
assert len(data_class.select([st.Equal('receipt_time', datetime.date(1, 1, 1))])) == 0
assert len(data_class.select([st.Greater('receipt_time', datetime.date(1, 1, 1))])) == 50
@ -1611,7 +1607,7 @@ def test_views_fts(pub):
def test_select_any_formdata(pub):
drop_formdef_tables()
now = datetime.datetime.now()
now = localtime()
cnt = 0
for i in range(5):
@ -1626,7 +1622,7 @@ def test_select_any_formdata(pub):
formdata.just_created()
formdata.user_id = '%s' % ((i + j) % 11)
# set receipt_time to make sure all entries are unique.
formdata.receipt_time = (now + datetime.timedelta(seconds=cnt)).timetuple()
formdata.receipt_time = now + datetime.timedelta(seconds=cnt)
formdata.status = ['wf-new', 'wf-accepted', 'wf-rejected', 'wf-finished'][(i + j) % 4]
if j < 5:
formdata.submission_channel = 'mail'
@ -1670,7 +1666,7 @@ def test_select_any_formdata(pub):
def test_load_all_evolutions_on_any_formdata(pub):
drop_formdef_tables()
now = datetime.datetime.now()
now = localtime()
cnt = 0
for i in range(5):
@ -1685,7 +1681,7 @@ def test_load_all_evolutions_on_any_formdata(pub):
formdata.just_created()
formdata.user_id = '%s' % ((i + j) % 11)
# set receipt_time to make sure all entries are unique.
formdata.receipt_time = (now + datetime.timedelta(seconds=cnt)).timetuple()
formdata.receipt_time = now + datetime.timedelta(seconds=cnt)
formdata.status = ['wf-new', 'wf-accepted', 'wf-rejected', 'wf-finished'][(i + j) % 4]
formdata.store()
cnt += 1
@ -1849,8 +1845,8 @@ def test_last_update_time(pub):
formdata1.just_created()
formdata1.evolution[0].comment = 'comment'
formdata1.jump_status('st1') # will add another evolution entry
formdata1.evolution[0].time = datetime.datetime(2015, 1, 1, 0, 0, 0).timetuple()
formdata1.evolution[1].time = datetime.datetime(2015, 1, 2, 0, 0, 0).timetuple()
formdata1.evolution[0].time = make_aware(datetime.datetime(2015, 1, 1, 0, 0, 0))
formdata1.evolution[1].time = make_aware(datetime.datetime(2015, 1, 2, 0, 0, 0))
formdata1.store()
formdata2 = data_class()
@ -1858,8 +1854,8 @@ def test_last_update_time(pub):
formdata2.just_created()
formdata2.evolution[0].comment = 'comment'
formdata2.jump_status('st1') # will add another evolution entry
formdata2.evolution[0].time = datetime.datetime(2015, 1, 3, 0, 0, 0).timetuple()
formdata2.evolution[1].time = datetime.datetime(2015, 1, 4, 0, 0, 0).timetuple()
formdata2.evolution[0].time = make_aware(datetime.datetime(2015, 1, 3, 0, 0, 0))
formdata2.evolution[1].time = make_aware(datetime.datetime(2015, 1, 4, 0, 0, 0))
formdata2.store()
cur.execute('''SELECT COUNT(*) FROM wcs_all_forms''')
@ -2167,7 +2163,7 @@ def test_migration_30_anonymize_evo_who(pub):
formdata.anonymised = datetime.datetime.now()
evo = Evolution(formdata)
evo.who = user.id
evo.time = time.localtime()
evo.time = localtime()
formdata.evolution.append(evo)
formdata.store()
@ -2789,7 +2785,7 @@ def test_workflow_traces_initial_migration(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.evolution[-1].time = (datetime.datetime.now() - datetime.timedelta(seconds=11)).timetuple()
formdata.evolution[-1].time = localtime() - datetime.timedelta(seconds=11)
action_part = ActionsTracingEvolutionPart()
action_part.event = 'frontoffice-created'
action_part.actions = [
@ -2798,7 +2794,7 @@ def test_workflow_traces_initial_migration(pub):
]
formdata.evolution[-1].add_part(action_part)
formdata.evolution.append(Evolution(formdata))
formdata.evolution[-1].time = (datetime.datetime.now() - datetime.timedelta(seconds=8)).timetuple()
formdata.evolution[-1].time = localtime() - datetime.timedelta(seconds=8)
action_part = ActionsTracingEvolutionPart()
action_part.event = 'timeout-jump'
action_part.event_args = ('xxx',)
@ -2807,7 +2803,7 @@ def test_workflow_traces_initial_migration(pub):
]
formdata.evolution[-1].add_part(action_part)
formdata.evolution.append(Evolution(formdata))
formdata.evolution[-1].time = (datetime.datetime.now() - datetime.timedelta(seconds=6)).timetuple()
formdata.evolution[-1].time = localtime() - datetime.timedelta(seconds=6)
action_part = ActionsTracingEvolutionPart()
action_part.event = 'global-action-timeout'
action_part.event_args = ('xxx2', 'xxx3')
@ -2816,7 +2812,7 @@ def test_workflow_traces_initial_migration(pub):
]
formdata.evolution[-1].add_part(action_part)
formdata.evolution.append(Evolution(formdata))
formdata.evolution[-1].time = (datetime.datetime.now() - datetime.timedelta(seconds=4)).timetuple()
formdata.evolution[-1].time = localtime() - datetime.timedelta(seconds=4)
action_part = ActionsTracingEvolutionPart()
action_part.event = 'global-api-trigger'
action_part.event_args = ('xxx2',)
@ -2829,7 +2825,7 @@ def test_workflow_traces_initial_migration(pub):
formdata2 = formdef.data_class()()
formdata2.just_created()
formdata2.evolution[-1].time = (datetime.datetime.now() - datetime.timedelta(seconds=2)).timetuple()
formdata2.evolution[-1].time = localtime() - datetime.timedelta(seconds=2)
action_part = ActionsTracingEvolutionPart()
action_part.event = 'workflow-created'
action_part.external_workflow_id = '1'

View File

@ -5,6 +5,7 @@ import time
import pytest
import responses
from django.utils.timezone import make_aware
from wcs import fields
from wcs.blocks import BlockDef
@ -122,7 +123,7 @@ def test_page_post_conditions(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['2'] = 'a'
formdata.data['4'] = 'a'
@ -156,7 +157,7 @@ def test_page_post_condition_invalid(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
testdef = TestDef.create_from_formdata(formdef, formdata)
with pytest.raises(TestError) as excinfo:
@ -181,7 +182,7 @@ def test_field_conditions(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'a'
formdata.data['2'] = 'xxx'
@ -219,7 +220,7 @@ def test_field_conditions_boolean(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = False
formdata.data['2'] = None
@ -259,7 +260,7 @@ def test_multi_page_condition(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'a'
formdata.data['3'] = 'xxx'
formdata.data['5'] = 'yyy'
@ -294,7 +295,7 @@ def test_validation_string_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = '1'
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -320,7 +321,7 @@ def test_validation_required_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
testdef = TestDef.create_from_formdata(formdef, formdata)
testdef.run(formdef)
@ -339,7 +340,7 @@ def test_validation_item_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'foo'
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -371,7 +372,7 @@ def test_validation_item_field_inside_block(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = {'data': [{'1': 'foo'}]}
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -404,7 +405,7 @@ def test_validation_optional_field_inside_required_block(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = {'data': [{'1': 'foo'}]}
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -434,7 +435,7 @@ def test_item_field_display_value(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'foo'
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -465,7 +466,7 @@ def test_item_field_structured_value(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data = {
'1': '2',
'1_raw': '2',
@ -526,7 +527,7 @@ def test_item_field_structured_value_inside_block(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = {
'data': [
{
@ -593,7 +594,7 @@ def test_item_field_card_data_source_live(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = str(carddata.id)
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -616,7 +617,7 @@ def test_validation_items_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = ['foo', 'baz']
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -643,7 +644,7 @@ def test_validation_email_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'test@entrouvert.com'
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -669,7 +670,7 @@ def test_validation_boolean_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = False
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -694,7 +695,7 @@ def test_validation_date_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = time.strptime('2022-07-19', '%Y-%m-%d')
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -727,7 +728,7 @@ def test_validation_map_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = '1.0;2.0'
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -750,7 +751,7 @@ def test_validation_file_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
upload = PicklableUpload('test.pdf', 'application/pdf', 'ascii')
upload.receive([b'first line', b'second line'])
@ -813,7 +814,7 @@ def test_validation_block_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = {'data': [{'1': 'b'}, {'1': 'a'}]}
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -864,7 +865,7 @@ def test_computed_field_support(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'zzz'
formdata.data['3'] = 'hop'
@ -904,13 +905,13 @@ def test_computed_field_support_complex_data(pub):
submitted_formdata = formdef.data_class()()
submitted_formdata.just_created()
submitted_formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
submitted_formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
submitted_formdata.data['2'] = ['a', 'bc']
submitted_formdata.store()
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
testdef = TestDef.create_from_formdata(formdef, formdata)
with pytest.raises(TestError) as excinfo:
@ -954,7 +955,7 @@ def test_computed_field_support_webservice(pub, http_requests):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
testdef = TestDef.create_from_formdata(formdef, formdata)
testdef.run(formdef)
@ -985,7 +986,7 @@ def test_computed_field_value_too_long(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
testdef = TestDef.create_from_formdata(formdef, formdata)
with pytest.raises(TestError):
@ -1024,7 +1025,7 @@ def test_computed_field_forms_template_access(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.store()
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -1062,7 +1063,7 @@ def test_expected_error(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = '123456'
testdef = TestDef.create_from_formdata(formdef, formdata)
@ -1107,7 +1108,7 @@ def test_expected_error_conditional_field(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
formdata.data['1'] = 'a'
formdata.data['2'] = 'b'
@ -1153,7 +1154,7 @@ def test_is_in_backoffice(pub):
formdata = formdef.data_class()()
formdata.just_created()
formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
formdata.receipt_time = make_aware(datetime.datetime(2021, 1, 1, 0, 0))
testdef = TestDef.create_from_formdata(formdef, formdata)
testdef.run(formdef)

View File

@ -1,10 +1,10 @@
import datetime
import json
import time
import pytest
import responses
from django.core.management import call_command
from django.utils.timezone import localtime
from wcs import fields
from wcs.carddef import CardDef
@ -305,10 +305,10 @@ def test_clean_deleted_users(pub):
formdata1 = data_class()
formdata1.user_id = user1.id
evo = Evolution(formdata=formdata1)
evo.time = time.localtime()
evo.time = localtime()
evo.who = user4.id
evo2 = Evolution(formdata=formdata1)
evo2.time = time.localtime()
evo2.time = localtime()
evo2.who = '_submitter'
formdata1.evolution = [evo, evo2]
formdata1.workflow_roles = {'_received': '_user:%s' % user5.id}

View File

@ -6,6 +6,7 @@ from unittest import mock
import pytest
import responses
from django.utils.timezone import localtime
from quixote import cleanup, get_publisher, get_response
from wcs import sessions, sql
@ -616,7 +617,7 @@ def test_anonymise(pub):
formdata.submission_context = {'foo': 'bar'}
formdata.store()
evo = Evolution(formdata) # add a new evolution
evo.time = time.localtime()
evo.time = localtime()
evo.status = formdata.status
evo.who = 42
evo.parts = [AttachmentEvolutionPart('hello.txt', fp=io.BytesIO(b'hello world'), varname='testfile')]
@ -1331,7 +1332,7 @@ def test_global_timeouts(pub, formdef_class):
pub.apply_global_action_timeouts()
assert formdef.data_class().get(formdata1.id).get_criticality_level_object().name == 'green'
formdata1.receipt_time = time.localtime(time.time() - 3 * 86400)
formdata1.receipt_time = localtime() - datetime.timedelta(days=3)
formdata1.store()
pub.apply_global_action_timeouts()
assert formdef.data_class().get(formdata1.id).get_criticality_level_object().name == 'yellow'
@ -1358,7 +1359,7 @@ def test_global_timeouts(pub, formdef_class):
pub.apply_global_action_timeouts()
assert formdef.data_class().get(formdata1.id).get_criticality_level_object().name == 'green'
formdata1.evolution[-1].time = time.localtime(time.time() - 3 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=3)
formdata1.store()
pub.apply_global_action_timeouts()
assert formdef.data_class().get(formdata1.id).get_criticality_level_object().name == 'yellow'
@ -1368,7 +1369,7 @@ def test_global_timeouts(pub, formdef_class):
# bad (obsolete) status: do nothing
trigger.anchor_status_first = 'wf-foobar'
workflow.store()
formdata1.evolution[-1].time = time.localtime(time.time() - 3 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=3)
formdata1.store()
pub.apply_global_action_timeouts()
assert formdef.data_class().get(formdata1.id).get_criticality_level_object().name == 'green'
@ -1378,18 +1379,18 @@ def test_global_timeouts(pub, formdef_class):
trigger.anchor_status_latest = None
workflow.store()
formdata1.evolution[-1].time = time.localtime()
formdata1.evolution[-1].time = localtime()
formdata1.store()
formdata1.jump_status('new')
formdata1.evolution[-1].time = time.localtime(time.time() - 7 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=7)
formdata1.jump_status('accepted')
formdata1.jump_status('new')
formdata1.evolution[-1].time = time.localtime(time.time() - 1 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=1)
pub.apply_global_action_timeouts()
assert formdef.data_class().get(formdata1.id).get_criticality_level_object().name == 'green'
formdata1.evolution[-1].time = time.localtime(time.time() - 4 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=4)
formdata1.store()
pub.apply_global_action_timeouts()
assert formdef.data_class().get(formdata1.id).get_criticality_level_object().name == 'yellow'
@ -1418,7 +1419,7 @@ def test_global_timeouts(pub, formdef_class):
# check trigger is not run on finalized formdata
formdata1.jump_status('finished')
formdata1.evolution[-1].time = time.localtime(time.time() - 4 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=4)
formdata1.store()
trigger.anchor = 'creation'
workflow.store()
@ -1430,7 +1431,7 @@ def test_global_timeouts(pub, formdef_class):
# endpoint
formdata1.jump_status('finished')
formdata1.evolution[-1].last_jump_datetime = None
formdata1.evolution[-1].time = time.localtime(time.time() - 4 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=4)
formdata1.store()
trigger.anchor = 'latest-arrival'
trigger.anchor_status_latest = 'wf-finished'
@ -1451,7 +1452,7 @@ def test_global_timeouts(pub, formdef_class):
# use python expression as anchor
# timestamp
formdata1.jump_status('new')
formdata1.evolution[-1].time = time.localtime(time.time() - 4 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=4)
formdata1.evolution[-1].last_jump_datetime = None
formdata1.store()
@ -1572,7 +1573,7 @@ def test_global_timeouts(pub, formdef_class):
# * invalid value
pub.loggederror_class.wipe()
formdata1.jump_status('accepted')
formdata1.evolution[-1].time = time.localtime(time.time() - 1 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=1)
formdata1.store()
pub.apply_global_action_timeouts()
assert formdef.data_class().get(formdata1.id).get_criticality_level_object().name == 'green'
@ -1597,7 +1598,7 @@ def test_global_timeouts(pub, formdef_class):
assert pub.loggederror_class.count() == 0
# * ok value, and timeout is triggered
formdata1.evolution[-1].time = time.localtime(time.time() - 4 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=4)
formdata1.store()
pub.apply_global_action_timeouts()
assert formdef.data_class().get(formdata1.id).get_criticality_level_object().name == 'yellow'
@ -1651,7 +1652,7 @@ def test_global_timeouts_finalized(pub, sql_queries, timeout):
formdata1.just_created()
formdata1.store()
formdata1.jump_status('finished')
formdata1.evolution[-1].time = time.localtime(time.time() - 4 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=4)
formdata1.store()
formdata2 = formdef.data_class()()
@ -1659,7 +1660,7 @@ def test_global_timeouts_finalized(pub, sql_queries, timeout):
formdata2.just_created()
formdata2.store()
formdata2.jump_status('finished')
formdata2.evolution[-1].time = time.localtime(time.time() - 1 * 86400)
formdata2.evolution[-1].time = localtime() - datetime.timedelta(days=1)
formdata2.store()
formdef2 = FormDef()
@ -1675,7 +1676,7 @@ def test_global_timeouts_finalized(pub, sql_queries, timeout):
formdata3.just_created()
formdata3.store()
formdata3.jump_status('finished')
formdata3.evolution[-1].time = time.localtime(time.time() - 6 * 86400)
formdata3.evolution[-1].time = localtime() - datetime.timedelta(days=6)
formdata3.store()
formdata4 = formdef2.data_class()()
@ -1683,7 +1684,7 @@ def test_global_timeouts_finalized(pub, sql_queries, timeout):
formdata4.just_created()
formdata4.store()
formdata4.jump_status('finished')
formdata4.evolution[-1].time = time.localtime(time.time() - 4 * 86400)
formdata4.evolution[-1].time = localtime() - datetime.timedelta(days=4)
formdata4.store()
pub.apply_global_action_timeouts()
@ -1735,18 +1736,18 @@ def test_global_timeouts_latest_arrival(pub):
formdata1.jump_status('new')
# enter in status 8 days ago
formdata1.evolution[-1].time = time.localtime(time.time() - 8 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=8)
formdata1.store()
# but get a new comment 1 day ago
formdata1.evolution.append(Evolution(formdata1))
formdata1.evolution[-1].time = time.localtime(time.time() - 1 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=1)
formdata1.evolution[-1].comment = 'plop'
formdata1.store()
pub.apply_global_action_timeouts()
# no change
assert formdef.data_class().get(formdata1.id).get_criticality_level_object().name == 'green'
formdata1.evolution[-1].time = time.localtime(time.time() - 5 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=5)
formdata1.store()
pub.apply_global_action_timeouts()
# change
@ -1757,7 +1758,7 @@ def test_global_timeouts_latest_arrival(pub):
formdata1.just_created()
formdata1.store()
formdata1.jump_status('new')
formdata1.evolution[-1].time = time.localtime(time.time() - 5 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=5)
formdata1.store()
formdata1.jump_status('accepted')
formdata1.store()
@ -1769,7 +1770,7 @@ def test_global_timeouts_latest_arrival(pub):
formdata1.just_created()
formdata1.store()
formdata1.jump_status('new')
formdata1.evolution[-1].time = time.localtime(time.time() - 5 * 86400)
formdata1.evolution[-1].time = localtime() - datetime.timedelta(days=5)
formdata1.store()
formdata1.jump_status('accepted')
formdata1.jump_status('finished')

View File

@ -1,5 +1,4 @@
import datetime
import time
from unittest import mock
import pytest
@ -40,11 +39,8 @@ def pub(request):
def rewind(formdata, seconds):
# utility function to move formdata back in time
def rewind_time(timetuple):
return time.localtime(datetime.datetime.fromtimestamp(time.mktime(timetuple) - seconds).timestamp())
formdata.receipt_time = rewind_time(formdata.receipt_time)
formdata.evolution[-1].time = rewind_time(formdata.evolution[-1].time)
formdata.receipt_time = formdata.receipt_time - datetime.timedelta(seconds=seconds)
formdata.evolution[-1].time = formdata.evolution[-1].time - datetime.timedelta(seconds=seconds)
def test_jump_nothing(pub):

View File

@ -18,11 +18,11 @@ import io
import itertools
import json
import textwrap
import time
import xml.etree.ElementTree as ET
from subprocess import PIPE, Popen
from django.utils.encoding import force_bytes
from django.utils.timezone import localtime
from quixote import get_publisher, get_request, get_response, get_session, redirect
from quixote.directory import Directory
from quixote.html import TemplateIO, htmltext
@ -2295,7 +2295,7 @@ class StatusChangeJob(AfterJob):
else:
item.status = new_status
evo = Evolution(formdata=item)
evo.time = time.localtime()
evo.time = localtime()
evo.status = new_status
evo.comment = str(_('Administrator reassigned status'))
if not item.evolution:

View File

@ -18,11 +18,11 @@ import base64
import copy
import datetime
import json
import time
import urllib.parse
from django.http import HttpResponse, HttpResponseBadRequest, JsonResponse
from django.utils.encoding import force_bytes
from django.utils.timezone import localtime, make_naive
from quixote import get_publisher, get_request, get_response, get_session, redirect
from quixote.directory import Directory
from quixote.errors import MethodNotAllowedError, RequestError
@ -153,6 +153,11 @@ def get_formdata_dict(formdata, user, consider_status_visibility=True):
d.update(formdata.get_static_substitution_variables(minimal=True))
if get_request().form.get('full') == 'on':
d.update(formdata.get_json_export_dict(include_files=False, user=user))
if d.get('form_receipt_datetime'):
d['form_receipt_datetime'] = make_naive(d['form_receipt_datetime'].replace(microsecond=0))
if d.get('form_last_update_datetime'):
d['form_last_update_datetime'] = make_naive(d['form_last_update_datetime'].replace(microsecond=0))
return d

Pour assurer la compatibilité des API les datetime y sont réduits pour continuer à n'avoir ni timezone, ni microsecondes.

Pour assurer la compatibilité des API les datetime y sont réduits pour continuer à n'avoir ni timezone, ni microsecondes.
@ -703,7 +708,7 @@ class ApiFormdefDirectory(Directory):
code.formdata = formdata # this will .store() the code
if meta.get('draft'):
formdata.status = 'draft'
formdata.receipt_time = time.localtime()
formdata.receipt_time = localtime()
formdata.store()
else:
formdata.just_created()

View File

@ -19,14 +19,13 @@ import datetime
import io
import json
import re
import time
import types
import urllib.parse
import zipfile
import vobject
from django.utils.encoding import force_str
from django.utils.timezone import is_naive, make_aware
from django.utils.timezone import is_naive, make_aware, make_naive, now
from quixote import get_publisher, get_request, get_response, get_session, redirect
from quixote.directory import Directory
from quixote.errors import RequestError
@ -2784,8 +2783,12 @@ class FormPage(Directory, TempfileDirectoryMixin):
'digest': (filled.digests or {}).get(digest_key),
'text': filled.get_display_label(digest_key=digest_key),
'url': filled.get_url(),
'receipt_time': datetime.datetime(*filled.receipt_time[:6]),
'last_update_time': datetime.datetime(*filled.last_update_time[:6]),
'receipt_time': make_naive(filled.receipt_time.replace(microsecond=0))
if filled.receipt_time
else None,

C'est fait à différents endroits, ça aurait pu être fait lors de l'encodage json mais ça aurait alors pris le risque de faire perdre de l'information sur les cas où existaient déjà microsecondes et timezone.

C'est fait à différents endroits, ça aurait pu être fait lors de l'encodage json mais ça aurait alors pris le risque de faire perdre de l'information sur les cas où existaient déjà microsecondes et timezone.
'last_update_time': make_naive(filled.last_update_time.replace(microsecond=0))
if filled.last_update_time
else None,
}
for filled in items
]
@ -3423,7 +3426,7 @@ class FormBackOfficeStatusPage(FormStatusPage):
formdata.backoffice_submission
and formdata.submission_agent_id == str(get_request().user.id)
and formdata.tracking_code
and time.time() - time.mktime(formdata.receipt_time) < 30 * 60
and (now() - formdata.receipt_time) < datetime.timedelta(minutes=30)
):
# keep displaying tracking code to submission agent for 30
# minutes after submission

View File

@ -14,10 +14,11 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
import time
import datetime
import urllib.parse
from django.utils.safestring import mark_safe
from django.utils.timezone import localtime, make_aware
from quixote import get_publisher, get_request, get_response, get_session, redirect
from quixote.directory import Directory
from quixote.html import TemplateIO, htmltext
@ -124,7 +125,7 @@ class FormFillPage(PublicFormFillPage):
formdata.submission_agent_id = str(get_request().user.id)
formdata.submission_context = {}
formdata.status = 'draft'
formdata.receipt_time = time.localtime()
formdata.receipt_time = localtime()
return formdata
def _q_index(self, *args, **kwargs):
@ -506,7 +507,9 @@ class SubmissionDirectory(Directory):
formdef._formdatas = [
x for x in data_class.get_ids(formdata_ids) if x.backoffice_submission is True
]
formdef._formdatas.sort(key=lambda x: x.receipt_time or time.gmtime(0))
formdef._formdatas.sort(
key=lambda x: x.receipt_time or make_aware(datetime.datetime(1900, 1, 1))
)
skip &= not (bool(formdef._formdatas))
if skip:
return

View File

@ -22,11 +22,10 @@ import html
import itertools
import json
import re
import time
import urllib.parse
from django.utils.html import strip_tags
from django.utils.timezone import localtime
from django.utils.timezone import localtime, make_naive
from quixote import get_publisher, get_request, get_session
from quixote.errors import RequestError
from quixote.html import htmltext
@ -213,7 +212,7 @@ class Evolution:
def get_json_export_dict(self, formdata_user, anonymise=False, include_files=True, prefetched_users=None):
data = {
'time': datetime.datetime(*self.time[:6]) if self.time else None,
'time': self.time,
'last_jump_datetime': self.last_jump_datetime,
}
if self.status:
@ -245,7 +244,7 @@ class Evolution:
@property
def datetime(self):
return datetime.datetime(*self.time[:6])
return self.time
def set_user(self, formdata, user, check_submitter=True):
if formdata.is_submitter(user) and check_submitter:
@ -481,7 +480,7 @@ class FormData(StorableObject):
# it should not be possible to have a formdef/carddef with a workflow without any status.
assert self.formdef.workflow.possible_status
self.receipt_time = time.localtime()
self.receipt_time = localtime()
self.status = 'wf-%s' % self.formdef.workflow.possible_status[0].id
# we add the initial status to the history, this makes it more readable
# afterwards (also this gets the (previous_status) code to work in all
@ -864,7 +863,7 @@ class FormData(StorableObject):
self.store()
return True
evo = Evolution(self)
evo.time = time.localtime()
evo.time = localtime()
evo.status = status
evo.who = user_id
self.evolution.append(evo)
@ -1048,9 +1047,7 @@ class FormData(StorableObject):
}
)
if self.receipt_time:
# always get receipt time as a datetime object, this handles
# both normal formdata (where receipt_time is a time.struct_time)
# and sql.AnyFormData where it's already a datetime object.
# always get receipt time as a datetime object
d['form_receipt_datetime'] = make_datetime(self.receipt_time)
if self.last_update_time:
d['form_last_update_datetime'] = make_datetime(self.last_update_time)
@ -1355,15 +1352,14 @@ class FormData(StorableObject):
if hasattr(self, '_last_update_time'):
return self._last_update_time
if self.evolution and self.evolution[-1].last_jump_datetime:
return self.evolution[-1].last_jump_datetime.timetuple()
return self.evolution[-1].last_jump_datetime
elif self.evolution and self.evolution[-1].time:
return self.evolution[-1].time
else:
return self.receipt_time
def set_last_update_time(self, value):
if isinstance(value, datetime.datetime):
value = value.timetuple()
assert isinstance(value, (type(None), datetime.datetime))
self._last_update_time = value
last_update_time = property(get_last_update_time, set_last_update_time)
@ -1545,8 +1541,12 @@ class FormData(StorableObject):
data['digests'] = self.digests
data['text'] = self.get_display_label(digest_key=digest_key)
data['url'] = self.get_url()
data['receipt_time'] = datetime.datetime(*self.receipt_time[:6])
data['last_update_time'] = datetime.datetime(*self.last_update_time[:6])
data['receipt_time'] = (
make_naive(self.receipt_time.replace(microsecond=0)) if self.receipt_time else None
)
data['last_update_time'] = (
make_naive(self.last_update_time.replace(microsecond=0)) if self.last_update_time else None
)
formdata_user = None
if include_fields or include_workflow or include_evolution:

View File

@ -27,6 +27,7 @@ except ImportError:
import ratelimit.utils
from django.utils.http import quote
from django.utils.timezone import localtime
from quixote import get_publisher, get_request, get_response, get_session, get_session_manager, redirect
from quixote.directory import AccessControlled, Directory
from quixote.errors import MethodNotAllowedError, RequestError
@ -1632,7 +1633,7 @@ class FormPage(Directory, TempfileDirectoryMixin, FormTemplateMixin):
formdata.page_no = page_no
formdata.page_id = self.get_page_id(page_no)
formdata.data = form_data
formdata.receipt_time = time.localtime()
formdata.receipt_time = localtime()
if not get_request().is_in_backoffice():
formdata.user = get_request().user
formdata.store()
@ -1719,7 +1720,7 @@ class FormPage(Directory, TempfileDirectoryMixin, FormTemplateMixin):
if page_no is not None:
filled.page_no = page_no
filled.page_id = self.get_page_id(page_no)
filled.receipt_time = time.localtime()
filled.receipt_time = localtime()
where = [Equal('status', 'draft')] + (where or [])
if get_request().is_in_backoffice():
# if submitting via backoffice store fhe formdata as is.
@ -1954,7 +1955,7 @@ class FormPage(Directory, TempfileDirectoryMixin, FormTemplateMixin):
else:
# add history entry
evo = Evolution(formdata=self.edited_data)
evo.time = time.localtime()
evo.time = localtime()
evo.who = user_id
self.edited_data.evolution.append(evo)
self.edited_data.store()

View File

@ -484,7 +484,7 @@ def do_formdef_tables(formdef, conn=None, cur=None, rebuild_views=False, rebuild
cur.execute(
'''CREATE TABLE %s (id serial PRIMARY KEY,
user_id varchar,
receipt_time timestamp,
receipt_time timestamptz,
anonymised timestamptz,
status varchar,
page_no varchar,
@ -497,8 +497,8 @@ def do_formdef_tables(formdef, conn=None, cur=None, rebuild_views=False, rebuild
'''CREATE TABLE %s_evolutions (id serial PRIMARY KEY,
who varchar,
status varchar,
time timestamp,
last_jump_datetime timestamp,
time timestamptz,
last_jump_datetime timestamptz,
comment text,
parts bytea,
formdata_id integer REFERENCES %s (id) ON DELETE CASCADE)'''
@ -509,12 +509,13 @@ def do_formdef_tables(formdef, conn=None, cur=None, rebuild_views=False, rebuild
cur.execute('LOCK TABLE %s;' % table_name)
cur.execute(
'''SELECT column_name FROM information_schema.columns
'''SELECT column_name, data_type FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = %s''',
(table_name,),
)
existing_fields = {x[0] for x in cur.fetchall()}
existing_field_types = {x[0]: x[1] for x in cur.fetchall()}

On récupère désomrais également le type des colonnes, pour ensuite faire le changement de type si nécessaire.

On récupère désomrais également le type des colonnes, pour ensuite faire le changement de type si nécessaire.
existing_fields = set(existing_field_types.keys())
needed_fields = {x[0] for x in formdef.data_class()._table_static_fields}
needed_fields.add('fts')
@ -536,6 +537,12 @@ def do_formdef_tables(formdef, conn=None, cur=None, rebuild_views=False, rebuild
if field_name not in existing_fields:
cur.execute('''ALTER TABLE %s ADD COLUMN %s %s''' % (table_name, field_name, field_type))
# store datetimes with timezone
if existing_field_types.get('receipt_time') not in (None, 'timestamp with time zone'):
cur.execute(f'ALTER TABLE {table_name} ALTER COLUMN receipt_time SET DATA TYPE timestamptz')
if existing_field_types.get('last_update_time') not in (None, 'timestamp with time zone'):
cur.execute(f'ALTER TABLE {table_name} ALTER COLUMN last_update_time SET DATA TYPE timestamptz')

C'est postgresql qui assure tout le boulot d'ajouter la bonne timezone partout et c'est très bien. (j'ai vérifié on a au niveau de postgresql timezone = 'Europe/Paris' et timezone = 'Indian/Reunion', correctement positionnés).

C'est postgresql qui assure tout le boulot d'ajouter la bonne timezone partout et c'est très bien. (j'ai vérifié on a au niveau de postgresql timezone = 'Europe/Paris' et timezone = 'Indian/Reunion', correctement positionnés).

pourquoi None ?

pourquoi None ?

Quand on récupère la liste des colonnes prsentes, last_update_time peut ne pas encore exister, et j'ai trouvé plus clair d'avoir la même ligne pour les deux colonnes. Une alternative serait d'ajouter last_update_time dès la création de la table mais faire cette partie proprement (exploiter _table_static_fields plutôt que juste dupliquer) demandait une refacto qui dépassait ce ticket.

Quand on récupère la liste des colonnes prsentes, last_update_time peut ne pas encore exister, et j'ai trouvé plus clair d'avoir la même ligne pour les deux colonnes. Une alternative serait d'ajouter last_update_time dès la création de la table mais faire cette partie proprement (exploiter _table_static_fields plutôt que juste dupliquer) demandait une refacto qui dépassait ce ticket.

ok ça se tient

ok ça se tient
# add new fields
for field in formdef.get_all_fields():
assert field.id is not None
@ -577,15 +584,24 @@ def do_formdef_tables(formdef, conn=None, cur=None, rebuild_views=False, rebuild
# migrations on _evolutions table
cur.execute(
'''SELECT column_name FROM information_schema.columns
'''SELECT column_name, data_type FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = '%s_evolutions'
'''
% table_name
)
evo_existing_fields = {x[0] for x in cur.fetchall()}
evo_existing_fields = {x[0]: x[1] for x in cur.fetchall()}
if 'last_jump_datetime' not in evo_existing_fields:
cur.execute('''ALTER TABLE %s_evolutions ADD COLUMN last_jump_datetime timestamp''' % table_name)
cur.execute(
'''ALTER TABLE %s_evolutions ADD COLUMN last_jump_datetime timestamptz''' % table_name
)
if evo_existing_fields.get('time') not in (None, 'timestamp with time zone'):
cur.execute(f'ALTER TABLE {table_name}_evolutions ALTER COLUMN time SET DATA TYPE timestamptz')
if evo_existing_fields.get('last_jump_datetime') not in (None, 'timestamp with time zone'):
cur.execute(
f'ALTER TABLE {table_name}_evolutions ALTER COLUMN last_jump_datetime SET DATA TYPE timestamptz'
)
if rebuild_views or len(existing_fields - needed_fields):
# views may have been dropped when dropping columns, so we recreate
@ -1329,13 +1345,19 @@ def drop_views(formdef, conn, cur):
(view_prefix,),
)
else:
# if there's no formdef specified, remove all form views
# if there's no formdef specified, remove all form & card views
cur.execute(
'''SELECT table_name FROM information_schema.views
WHERE table_schema = 'public'
AND table_name LIKE %s''',
('wcs\\_view\\_%',),
)
cur.execute(
'''SELECT table_name FROM information_schema.views
WHERE table_schema = 'public'
AND table_name LIKE %s''',
('wcs\\_carddata\\_view\\_%',),

Je me suis rendu compte qu'en local j'avais des vues sur les fiches, et ça pouvait bloquer le changement de type de colonne, donc ça les dégage.

Je me suis rendu compte qu'en local j'avais des vues sur les fiches, et ça pouvait bloquer le changement de type de colonne, donc ça les dégage.
)
view_names = []
while True:
row = cur.fetchone()
@ -1485,13 +1507,13 @@ def do_global_views(conn, cur):
formdef_id integer NOT NULL,
id integer NOT NULL,
user_id character varying,
receipt_time timestamp without time zone,
receipt_time timestamp with time zone,
status character varying,
id_display character varying,
submission_agent_id character varying,
submission_channel character varying,
backoffice_submission boolean,
last_update_time timestamp without time zone,
last_update_time timestamp with time zone,
digests jsonb,
user_label character varying,
concerned_roles_array text[],
@ -1524,17 +1546,22 @@ def do_global_views(conn, cur):
cur.execute('LOCK TABLE wcs_all_forms;')
cur.execute(
'''SELECT column_name FROM information_schema.columns
'''SELECT column_name, data_type FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = %s''',
('wcs_all_forms',),
)
existing_fields = {x[0] for x in cur.fetchall()}
existing_fields = {x[0]: x[1] for x in cur.fetchall()}
if 'statistics_data' not in existing_fields:
cur.execute('ALTER TABLE wcs_all_forms ADD COLUMN statistics_data jsonb')
if 'relations_data' not in existing_fields:
cur.execute('ALTER TABLE wcs_all_forms ADD COLUMN relations_data jsonb')
if existing_fields.get('receipt_time') not in (None, 'timestamp with time zone'):
cur.execute('ALTER TABLE wcs_all_forms ALTER COLUMN receipt_time SET DATA TYPE timestamptz')
if existing_fields.get('last_update_time') not in (None, 'timestamp with time zone'):
cur.execute('ALTER TABLE wcs_all_forms ALTER COLUMN last_update_time SET DATA TYPE timestamptz')
clean_global_views(conn, cur)
for category in wcs.categories.Category.select():
@ -2198,7 +2225,7 @@ class SqlDataMixin(SqlMixin):
_table_static_fields = [
('id', 'serial'),
('user_id', 'varchar'),
('receipt_time', 'timestamp'),
('receipt_time', 'timestamptz'),
('status', 'varchar'),
('page_no', 'varchar'),
('page_id', 'varchar'),
@ -2221,7 +2248,7 @@ class SqlDataMixin(SqlMixin):
('submission_agent_id', 'varchar'),
('submission_channel', 'varchar'),
('criticality_level', 'int'),
('last_update_time', 'timestamp'),
('last_update_time', 'timestamptz'),
('digests', 'jsonb'),
('user_label', 'varchar'),
('auto_geoloc', 'point'),
@ -2265,8 +2292,6 @@ class SqlDataMixin(SqlMixin):
o._sql_id, o.who, o.status, o.time, o.last_jump_datetime, o.comment = (
str_encode(x) for x in tuple(row[:6])
)
if o.time:
o.time = o.time.timetuple()
if row[6]:
o.parts = LazyEvolutionList(row[6])
return o
@ -2409,14 +2434,8 @@ class SqlDataMixin(SqlMixin):
# if evolution was loaded it may have been been modified, and last update time
# should then be refreshed.
delattr(self, '_last_update_time')
if self.last_update_time:
sql_dict['last_update_time'] = datetime.datetime.fromtimestamp(time.mktime(self.last_update_time))
else:
sql_dict['last_update_time'] = None
if self.receipt_time:
sql_dict['receipt_time'] = datetime.datetime.fromtimestamp(time.mktime(self.receipt_time))
else:
sql_dict['receipt_time'] = None
sql_dict['last_update_time'] = self.last_update_time
sql_dict['receipt_time'] = self.receipt_time
if self.workflow_roles:
sql_dict['workflow_roles_array'] = []
for x in self.workflow_roles.values():
@ -2538,7 +2557,7 @@ class SqlDataMixin(SqlMixin):
{
'who': evo.who,
'status': evo.status,
'time': datetime.datetime.fromtimestamp(time.mktime(evo.time)),
'time': evo.time,
'last_jump_datetime': evo.last_jump_datetime,
'comment': evo.comment,
'formdata_id': self.id,
@ -2619,8 +2638,6 @@ class SqlDataMixin(SqlMixin):
o = cls()
for static_field, value in zip(cls._table_static_fields, tuple(row[: len(cls._table_static_fields)])):
setattr(o, static_field[0], str_encode(value))
if o.receipt_time:
o.receipt_time = o.receipt_time.timetuple()
for attr in ('workflow_data', 'workflow_roles', 'submission_context', 'prefilling_data'):
if getattr(o, attr):
setattr(o, attr, pickle_loads(getattr(o, attr)))
@ -4282,7 +4299,7 @@ class WorkflowTrace(SqlMixin):
elif trace.event in ('workflow-created',):
trace.event_args['display_id'] = part.event_args[0]
trace.status_id = status_id
trace.timestamp = make_aware(datetime.datetime(*evo.time[:6]), is_dst=True)
trace.timestamp = evo.time
trace.store()
for action in part.actions or []:
trace = cls(formdata=formdata)
@ -5046,7 +5063,7 @@ def get_period_total(
# latest migration, number + description (description is not used
# programmaticaly but will make sure git conflicts if two migrations are
# separately added with the same number)
SQL_LEVEL = (101, 'add page_id on formdata')
SQL_LEVEL = (102, 'switch formdata datetime columns to timestamptz')
def migrate_global_views(conn, cur):
@ -5316,20 +5333,23 @@ def migrate():
continue
for formdata in formdef.data_class().select_iterator():
formdata._set_auto_fields(cur) # build digests
if sql_level < 91:
if sql_level < 102:
# 58: add workflow_merged_roles_dict as a jsonb column with
# combined formdef and formdata value.
# 69: add auto_geoloc field to form/card tables
# 80: add jsonb column to hold statistics data
# 91: add jsonb column to hold relations data
# 102: switch formdata datetime columns to timestamptz
drop_views(None, conn, cur)
for formdef in FormDef.select() + CardDef.select():
do_formdef_tables(formdef, rebuild_views=False, rebuild_global_views=False)
migrate_views(conn, cur)
set_reindex('formdata', 'needed', conn=conn, cur=cur)
Review

migrate_views fait déjà:

def migrate_views(conn, cur):
    drop_views(None, conn, cur)
    for formdef in FormDef.select() + CardDef.select():
        # make sure all formdefs have up-to-date views
        do_formdef_tables(formdef, conn=conn, cur=cur, rebuild_views=True, rebuild_global_views=False)
    migrate_global_views(conn, cur)

Ca fait pas redondant ?

migrate_views fait déjà: ```python def migrate_views(conn, cur): drop_views(None, conn, cur) for formdef in FormDef.select() + CardDef.select(): # make sure all formdefs have up-to-date views do_formdef_tables(formdef, conn=conn, cur=cur, rebuild_views=True, rebuild_global_views=False) migrate_global_views(conn, cur) ``` Ca fait pas redondant ?
Review

Ca fait pas redondant ?

Il me semble qu'en effet désormais, avec l'ajout du drop_views() (qui doit être lancé avant le do_formdef_tables, sinon on peut avoir postgresql en erreur parce qu'on modifie le type d'une colonne reprise dans une vue), cette partie pourrait être réduite à migrate_views().

J'aurais juste la crainte d'une refacto où à un moment le migrate_views ne ferait plus rien parce que feature flag; c'est assez flou mais j'aimerais bien laisser ainsi.

> Ca fait pas redondant ? Il me semble qu'en effet désormais, avec l'ajout du drop_views() (qui doit être lancé avant le do_formdef_tables, sinon on peut avoir postgresql en erreur parce qu'on modifie le type d'une colonne reprise dans une vue), cette partie pourrait être réduite à migrate_views(). J'aurais juste la crainte d'une refacto où à un moment le migrate_views ne ferait plus rien parce que feature flag; c'est assez flou mais j'aimerais bien laisser ainsi.
Review

ok

ok
if sql_level < 99:
if sql_level < 102:
# 81: add statistics data column to wcs_all_forms
# 82: add statistics data column to wcs_all_forms, for real
# 99: add more indexes
# 102: switch formdata datetime columns to timestamptz
migrate_global_views(conn, cur)
if sql_level < 60:
# 59: switch wcs_all_forms to a trigger-maintained table

View File

@ -15,10 +15,10 @@
# along with this program; if not, see <http://www.gnu.org/licenses/>.
import collections
import time
import xml.etree.ElementTree as ET
from django.utils.functional import cached_property
from django.utils.timezone import localtime
from quixote import get_publisher, get_request, get_session
from quixote.html import TemplateIO, htmltext
@ -707,7 +707,7 @@ class CreateFormdataWorkflowStatusItem(WorkflowStatusItem):
return
new_formdata = formdef.data_class()()
new_formdata.receipt_time = time.localtime()
new_formdata.receipt_time = localtime()
self.assign_user(dest=new_formdata, src=formdata)
@ -736,7 +736,7 @@ class CreateFormdataWorkflowStatusItem(WorkflowStatusItem):
if self.draft:
new_formdata.status = 'draft'
new_formdata.receipt_time = time.localtime()
new_formdata.receipt_time = localtime()
new_formdata.store()
if formdef.enable_tracking_codes:
code.formdata = new_formdata # this will .store() the code

View File

@ -15,8 +15,8 @@
# along with this program; if not, see <http://www.gnu.org/licenses/>.
import copy
import time
from django.utils.timezone import localtime
from quixote import get_publisher
from wcs.formdata import Evolution
@ -59,7 +59,7 @@ class EditCarddataWorkflowStatusItem(CreateCarddataWorkflowStatusItem, ExternalW
with get_publisher().substitutions.freeze():
last_evo = target_data.evolution[-1]
evo = Evolution(formdata=target_data)
evo.time = time.localtime()
evo.time = localtime()
evo.status = target_data.status
target_data.evolution.append(evo)
part = ContentSnapshotPart.take(formdata=target_data, old_data=old_data)

View File

@ -20,9 +20,8 @@ import itertools
import json
import math
import os
import time
from django.utils.timezone import now
from django.utils.timezone import localtime
from quixote import get_publisher, get_request, get_response, redirect
from quixote.directory import Directory
from quixote.html import htmltext
@ -57,7 +56,7 @@ class WorkflowTriggeredEvolutionPart(EvolutionPart):
self.trigger_name = trigger_name
self.content = content
self.kind = kind
self.datetime = now()
self.datetime = localtime()
self.trigger_name_key = misc.simplify(self.trigger_name, space='_')
@ -324,7 +323,7 @@ class JumpWorkflowStatusItem(WorkflowStatusJumpItem):
return False
last = formdata.last_update_time
if last and timeout_seconds:
diff = time.time() - time.mktime(last)
diff = (localtime() - last).total_seconds()
if diff < timeout_seconds:
return False
@ -395,7 +394,7 @@ def _apply_timeouts(publisher, **kwargs):
Null('anonymised'),
LessOrEqual(
'last_update_time',
(datetime.datetime.now() - datetime.timedelta(seconds=delay)).timetuple(),
localtime() - datetime.timedelta(seconds=delay),
),
]
formdatas = formdata_class.select_iterator(criterias, ignore_errors=True, itersize=200)

View File

@ -14,8 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
import time
from django.utils.timezone import localtime
from quixote import get_publisher, get_request, get_session
from wcs.formdef import FormDef
@ -82,7 +81,7 @@ class ResubmitWorkflowStatusItem(WorkflowStatusItem):
formdef = FormDef.get_by_urlname(self.formdef_slug)
new_formdata = formdef.data_class()()
new_formdata.status = 'draft'
new_formdata.receipt_time = time.localtime()
new_formdata.receipt_time = localtime()
new_formdata.user_id = formdata.user_id
new_formdata.submission_context = (formdata.submission_context or {}).copy()
new_formdata.submission_channel = formdata.submission_channel

View File

@ -130,7 +130,7 @@ def perform_items(items, formdata, depth=20, user=None, global_action=False):
evo = Evolution(formdata)
if global_action:
evo.set_user(formdata=formdata, user=user)
evo.time = time.localtime()
evo.time = localtime()
evo.status = formdata.status
formdata.evolution.append(evo)
formdata.store()
@ -2367,7 +2367,7 @@ class SerieOfActionsMixin:
def get_action_form(self, filled, user, displayed_fields=None):
form = Form(enctype='multipart/form-data', use_tokens=False)
form.attrs['id'] = 'wf-actions'
form.add_hidden('_ts', str(time.mktime(filled.last_update_time)))
form.add_hidden('_ts', str(filled.last_update_time.timestamp()))
for item in self.items:
if not item.check_auth(filled, user):
continue
@ -2413,9 +2413,9 @@ class SerieOfActionsMixin:
return messages
def handle_form(self, form, filled, user, evo, check_replay=True):
if check_replay and form.get('_ts') != str(time.mktime(filled.last_update_time)):
if check_replay and form.get('_ts') != str(filled.last_update_time.timestamp()):
raise ReplayException()
evo.time = time.localtime()
evo.time = localtime()
evo.set_user(formdata=filled, user=user, check_submitter=get_request().is_in_frontoffice())
if not filled.evolution:
filled.evolution = []