meta-edc 1.1.4__py3-none-any.whl → 1.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,10 +21,16 @@
21
21
  "plus = activate(dotenv_file=env_file)"
22
22
  ]
23
23
  },
24
+ {
25
+ "cell_type": "markdown",
26
+ "id": "1",
27
+ "metadata": {},
28
+ "source": []
29
+ },
24
30
  {
25
31
  "cell_type": "code",
26
32
  "execution_count": null,
27
- "id": "1",
33
+ "id": "2",
28
34
  "metadata": {},
29
35
  "outputs": [],
30
36
  "source": [
@@ -53,7 +59,7 @@
53
59
  {
54
60
  "cell_type": "code",
55
61
  "execution_count": null,
56
- "id": "2",
62
+ "id": "3",
57
63
  "metadata": {},
58
64
  "outputs": [],
59
65
  "source": [
@@ -70,7 +76,7 @@
70
76
  {
71
77
  "cell_type": "code",
72
78
  "execution_count": null,
73
- "id": "3",
79
+ "id": "4",
74
80
  "metadata": {},
75
81
  "outputs": [],
76
82
  "source": [
@@ -112,7 +118,7 @@
112
118
  {
113
119
  "cell_type": "code",
114
120
  "execution_count": null,
115
- "id": "4",
121
+ "id": "5",
116
122
  "metadata": {},
117
123
  "outputs": [],
118
124
  "source": [
@@ -122,7 +128,7 @@
122
128
  {
123
129
  "cell_type": "code",
124
130
  "execution_count": null,
125
- "id": "5",
131
+ "id": "6",
126
132
  "metadata": {},
127
133
  "outputs": [],
128
134
  "source": [
@@ -165,7 +171,7 @@
165
171
  {
166
172
  "cell_type": "code",
167
173
  "execution_count": null,
168
- "id": "6",
174
+ "id": "7",
169
175
  "metadata": {},
170
176
  "outputs": [],
171
177
  "source": [
@@ -175,7 +181,7 @@
175
181
  {
176
182
  "cell_type": "code",
177
183
  "execution_count": null,
178
- "id": "7",
184
+ "id": "8",
179
185
  "metadata": {},
180
186
  "outputs": [],
181
187
  "source": [
@@ -186,7 +192,7 @@
186
192
  {
187
193
  "cell_type": "code",
188
194
  "execution_count": null,
189
- "id": "8",
195
+ "id": "9",
190
196
  "metadata": {},
191
197
  "outputs": [],
192
198
  "source": [
@@ -198,7 +204,7 @@
198
204
  {
199
205
  "cell_type": "code",
200
206
  "execution_count": null,
201
- "id": "9",
207
+ "id": "10",
202
208
  "metadata": {},
203
209
  "outputs": [],
204
210
  "source": [
@@ -212,7 +218,7 @@
212
218
  {
213
219
  "cell_type": "code",
214
220
  "execution_count": null,
215
- "id": "10",
221
+ "id": "11",
216
222
  "metadata": {},
217
223
  "outputs": [],
218
224
  "source": [
@@ -235,7 +241,7 @@
235
241
  {
236
242
  "cell_type": "code",
237
243
  "execution_count": null,
238
- "id": "11",
244
+ "id": "12",
239
245
  "metadata": {},
240
246
  "outputs": [],
241
247
  "source": [
@@ -252,7 +258,7 @@
252
258
  {
253
259
  "cell_type": "code",
254
260
  "execution_count": null,
255
- "id": "12",
261
+ "id": "13",
256
262
  "metadata": {},
257
263
  "outputs": [],
258
264
  "source": [
@@ -262,7 +268,7 @@
262
268
  {
263
269
  "cell_type": "code",
264
270
  "execution_count": null,
265
- "id": "13",
271
+ "id": "14",
266
272
  "metadata": {},
267
273
  "outputs": [],
268
274
  "source": [
@@ -299,7 +305,7 @@
299
305
  {
300
306
  "cell_type": "code",
301
307
  "execution_count": null,
302
- "id": "14",
308
+ "id": "15",
303
309
  "metadata": {},
304
310
  "outputs": [],
305
311
  "source": [
@@ -309,7 +315,7 @@
309
315
  {
310
316
  "cell_type": "code",
311
317
  "execution_count": null,
312
- "id": "15",
318
+ "id": "16",
313
319
  "metadata": {},
314
320
  "outputs": [],
315
321
  "source": [
@@ -321,7 +327,7 @@
321
327
  {
322
328
  "cell_type": "code",
323
329
  "execution_count": null,
324
- "id": "16",
330
+ "id": "17",
325
331
  "metadata": {},
326
332
  "outputs": [],
327
333
  "source": [
@@ -353,7 +359,7 @@
353
359
  {
354
360
  "cell_type": "code",
355
361
  "execution_count": null,
356
- "id": "17",
362
+ "id": "18",
357
363
  "metadata": {},
358
364
  "outputs": [],
359
365
  "source": [
@@ -374,7 +380,7 @@
374
380
  {
375
381
  "cell_type": "code",
376
382
  "execution_count": null,
377
- "id": "18",
383
+ "id": "19",
378
384
  "metadata": {},
379
385
  "outputs": [],
380
386
  "source": [
@@ -385,7 +391,7 @@
385
391
  {
386
392
  "cell_type": "code",
387
393
  "execution_count": null,
388
- "id": "19",
394
+ "id": "20",
389
395
  "metadata": {},
390
396
  "outputs": [],
391
397
  "source": [
@@ -395,7 +401,7 @@
395
401
  {
396
402
  "cell_type": "code",
397
403
  "execution_count": null,
398
- "id": "20",
404
+ "id": "21",
399
405
  "metadata": {},
400
406
  "outputs": [],
401
407
  "source": [
@@ -408,7 +414,7 @@
408
414
  {
409
415
  "cell_type": "code",
410
416
  "execution_count": null,
411
- "id": "21",
417
+ "id": "22",
412
418
  "metadata": {},
413
419
  "outputs": [],
414
420
  "source": [
@@ -426,7 +432,7 @@
426
432
  {
427
433
  "cell_type": "code",
428
434
  "execution_count": null,
429
- "id": "22",
435
+ "id": "23",
430
436
  "metadata": {},
431
437
  "outputs": [],
432
438
  "source": [
@@ -447,7 +453,7 @@
447
453
  {
448
454
  "cell_type": "code",
449
455
  "execution_count": null,
450
- "id": "23",
456
+ "id": "24",
451
457
  "metadata": {},
452
458
  "outputs": [],
453
459
  "source": [
@@ -463,12 +469,13 @@
463
469
  {
464
470
  "cell_type": "code",
465
471
  "execution_count": null,
466
- "id": "24",
472
+ "id": "25",
467
473
  "metadata": {},
468
474
  "outputs": [],
469
475
  "source": [
470
476
  "# now lets look at the stock\n",
471
- "df_stock = read_frame(Stock.objects.values(\"code\", \"lot_id\", \"container__name\", \"confirmed\", \"allocated\", \"dispensed\", \"qty_in\", \"qty_out\", \"unit_qty_in\", \"unit_qty_out\").all(), verbose=False)\n",
477
+ "df_stock = read_frame(Stock.objects.values(\"code\", \"lot_id\", \"container__name\", \"confirmation\", \"allocation\", \"dispense\", \"qty_in\", \"qty_out\", \"unit_qty_in\", \"unit_qty_out\").all(), verbose=False)\n",
478
+ "df_stock = df_stock.fillna(pd.NA)\n",
472
479
  "\n",
473
480
  "# merge in assignment\n",
474
481
  "df_lot = read_frame(Lot.objects.values(\"id\", \"assignment__name\").all(), verbose=False)\n",
@@ -481,7 +488,7 @@
481
488
  {
482
489
  "cell_type": "code",
483
490
  "execution_count": null,
484
- "id": "25",
491
+ "id": "26",
485
492
  "metadata": {},
486
493
  "outputs": [],
487
494
  "source": [
@@ -498,7 +505,7 @@
498
505
  {
499
506
  "cell_type": "code",
500
507
  "execution_count": null,
501
- "id": "26",
508
+ "id": "27",
502
509
  "metadata": {},
503
510
  "outputs": [],
504
511
  "source": [
@@ -511,7 +518,7 @@
511
518
  {
512
519
  "cell_type": "code",
513
520
  "execution_count": null,
514
- "id": "27",
521
+ "id": "28",
515
522
  "metadata": {},
516
523
  "outputs": [],
517
524
  "source": [
@@ -533,7 +540,7 @@
533
540
  {
534
541
  "cell_type": "code",
535
542
  "execution_count": null,
536
- "id": "28",
543
+ "id": "29",
537
544
  "metadata": {},
538
545
  "outputs": [],
539
546
  "source": [
@@ -548,7 +555,7 @@
548
555
  {
549
556
  "cell_type": "code",
550
557
  "execution_count": null,
551
- "id": "29",
558
+ "id": "30",
552
559
  "metadata": {},
553
560
  "outputs": [],
554
561
  "source": [
@@ -563,7 +570,7 @@
563
570
  {
564
571
  "cell_type": "code",
565
572
  "execution_count": null,
566
- "id": "30",
573
+ "id": "31",
567
574
  "metadata": {},
568
575
  "outputs": [],
569
576
  "source": [
@@ -575,7 +582,7 @@
575
582
  {
576
583
  "cell_type": "code",
577
584
  "execution_count": null,
578
- "id": "31",
585
+ "id": "32",
579
586
  "metadata": {},
580
587
  "outputs": [],
581
588
  "source": [
@@ -587,7 +594,7 @@
587
594
  {
588
595
  "cell_type": "code",
589
596
  "execution_count": null,
590
- "id": "32",
597
+ "id": "33",
591
598
  "metadata": {},
592
599
  "outputs": [],
593
600
  "source": [
@@ -598,7 +605,7 @@
598
605
  {
599
606
  "cell_type": "code",
600
607
  "execution_count": null,
601
- "id": "33",
608
+ "id": "34",
602
609
  "metadata": {},
603
610
  "outputs": [],
604
611
  "source": [
@@ -609,7 +616,7 @@
609
616
  {
610
617
  "cell_type": "code",
611
618
  "execution_count": null,
612
- "id": "34",
619
+ "id": "35",
613
620
  "metadata": {},
614
621
  "outputs": [],
615
622
  "source": [
@@ -620,18 +627,18 @@
620
627
  {
621
628
  "cell_type": "code",
622
629
  "execution_count": null,
623
- "id": "35",
630
+ "id": "36",
624
631
  "metadata": {},
625
632
  "outputs": [],
626
633
  "source": [
627
634
  "# tablets: total bottles available / not yet dispensed BY ASSIGNMENT\n",
628
635
  "# the total matches the total above for column \"bal\"\n",
629
- "df4 = df_stock[(df_stock.container_type==\"Bottle\") & (df_stock.confirmed==True) & (df_stock.dispensed==True)].groupby(by=[\"assignment\"]).unit_qty_in.sum().reset_index()\n",
636
+ "df4 = df_stock[(df_stock.container_type==\"Bottle\") & ~(df_stock.confirmation.isna()) & ~(df_stock.dispense.isna())].groupby(by=[\"assignment\"]).unit_qty_in.sum().reset_index()\n",
630
637
  "df4[\"subtotal\"] = np.nan\n",
631
638
  "df4.loc[len(df4)] = {\"subtotal\": df4.unit_qty_in.sum()}\n",
632
- "df4[\"dispensed\"] = True\n",
639
+ "df[\"dispensed\"] = True\n",
633
640
  "\n",
634
- "df5 = df_stock[(df_stock.container_type==\"Bottle\") & (df_stock.confirmed==True) & (df_stock.dispensed==False)].groupby(by=[\"assignment\"]).unit_qty_in.sum().reset_index()\n",
641
+ "df5 = df_stock[(df_stock.container_type==\"Bottle\") & ~(df_stock.confirmation.isna()) & (df_stock.dispense.isna())].groupby(by=[\"assignment\"]).unit_qty_in.sum().reset_index()\n",
635
642
  "df5.loc[df5.assignment==\"placebo\", \"unit_qty_in\"] += placebo_unlabelled\n",
636
643
  "df5.loc[df5.assignment==\"active\", \"unit_qty_in\"] += active_unlabelled\n",
637
644
  "df5[\"subtotal\"] = np.nan\n",
@@ -646,14 +653,6 @@
646
653
  "df6"
647
654
  ]
648
655
  },
649
- {
650
- "cell_type": "code",
651
- "execution_count": null,
652
- "id": "36",
653
- "metadata": {},
654
- "outputs": [],
655
- "source": []
656
- },
657
656
  {
658
657
  "cell_type": "code",
659
658
  "execution_count": null,
@@ -668,14 +667,6 @@
668
667
  "id": "38",
669
668
  "metadata": {},
670
669
  "outputs": [],
671
- "source": []
672
- },
673
- {
674
- "cell_type": "code",
675
- "execution_count": null,
676
- "id": "39",
677
- "metadata": {},
678
- "outputs": [],
679
670
  "source": [
680
671
  "from meta_visit_schedule.constants import MONTH36\n",
681
672
  "\n",
@@ -685,7 +676,7 @@
685
676
  {
686
677
  "cell_type": "code",
687
678
  "execution_count": null,
688
- "id": "40",
679
+ "id": "39",
689
680
  "metadata": {},
690
681
  "outputs": [],
691
682
  "source": [
@@ -724,7 +715,7 @@
724
715
  {
725
716
  "cell_type": "code",
726
717
  "execution_count": null,
727
- "id": "41",
718
+ "id": "40",
728
719
  "metadata": {},
729
720
  "outputs": [],
730
721
  "source": [
@@ -744,7 +735,7 @@
744
735
  {
745
736
  "cell_type": "code",
746
737
  "execution_count": null,
747
- "id": "42",
738
+ "id": "41",
748
739
  "metadata": {},
749
740
  "outputs": [],
750
741
  "source": [
@@ -755,7 +746,7 @@
755
746
  {
756
747
  "cell_type": "code",
757
748
  "execution_count": null,
758
- "id": "43",
749
+ "id": "42",
759
750
  "metadata": {},
760
751
  "outputs": [],
761
752
  "source": [
@@ -766,7 +757,7 @@
766
757
  {
767
758
  "cell_type": "code",
768
759
  "execution_count": null,
769
- "id": "44",
760
+ "id": "43",
770
761
  "metadata": {},
771
762
  "outputs": [],
772
763
  "source": []
@@ -774,7 +765,7 @@
774
765
  {
775
766
  "cell_type": "code",
776
767
  "execution_count": null,
777
- "id": "45",
768
+ "id": "44",
778
769
  "metadata": {},
779
770
  "outputs": [],
780
771
  "source": [
@@ -800,7 +791,7 @@
800
791
  {
801
792
  "cell_type": "code",
802
793
  "execution_count": null,
803
- "id": "46",
794
+ "id": "45",
804
795
  "metadata": {},
805
796
  "outputs": [],
806
797
  "source": [
@@ -810,7 +801,7 @@
810
801
  {
811
802
  "cell_type": "code",
812
803
  "execution_count": null,
813
- "id": "47",
804
+ "id": "46",
814
805
  "metadata": {},
815
806
  "outputs": [],
816
807
  "source": [
@@ -833,7 +824,7 @@
833
824
  {
834
825
  "cell_type": "code",
835
826
  "execution_count": null,
836
- "id": "48",
827
+ "id": "47",
837
828
  "metadata": {},
838
829
  "outputs": [],
839
830
  "source": [
@@ -843,7 +834,7 @@
843
834
  {
844
835
  "cell_type": "code",
845
836
  "execution_count": null,
846
- "id": "49",
837
+ "id": "48",
847
838
  "metadata": {},
848
839
  "outputs": [],
849
840
  "source": [
@@ -859,7 +850,7 @@
859
850
  {
860
851
  "cell_type": "code",
861
852
  "execution_count": null,
862
- "id": "50",
853
+ "id": "49",
863
854
  "metadata": {},
864
855
  "outputs": [],
865
856
  "source": [
@@ -870,7 +861,7 @@
870
861
  {
871
862
  "cell_type": "code",
872
863
  "execution_count": null,
873
- "id": "51",
864
+ "id": "50",
874
865
  "metadata": {},
875
866
  "outputs": [],
876
867
  "source": [
@@ -890,7 +881,7 @@
890
881
  {
891
882
  "cell_type": "code",
892
883
  "execution_count": null,
893
- "id": "52",
884
+ "id": "51",
894
885
  "metadata": {},
895
886
  "outputs": [],
896
887
  "source": []
@@ -898,7 +889,7 @@
898
889
  {
899
890
  "cell_type": "code",
900
891
  "execution_count": null,
901
- "id": "53",
892
+ "id": "52",
902
893
  "metadata": {},
903
894
  "outputs": [],
904
895
  "source": []
@@ -906,7 +897,7 @@
906
897
  {
907
898
  "cell_type": "code",
908
899
  "execution_count": null,
909
- "id": "54",
900
+ "id": "53",
910
901
  "metadata": {},
911
902
  "outputs": [],
912
903
  "source": [
@@ -916,7 +907,7 @@
916
907
  {
917
908
  "cell_type": "code",
918
909
  "execution_count": null,
919
- "id": "55",
910
+ "id": "54",
920
911
  "metadata": {},
921
912
  "outputs": [],
922
913
  "source": [
@@ -926,7 +917,7 @@
926
917
  {
927
918
  "cell_type": "code",
928
919
  "execution_count": null,
929
- "id": "56",
920
+ "id": "55",
930
921
  "metadata": {},
931
922
  "outputs": [],
932
923
  "source": [
@@ -937,7 +928,7 @@
937
928
  {
938
929
  "cell_type": "code",
939
930
  "execution_count": null,
940
- "id": "57",
931
+ "id": "56",
941
932
  "metadata": {},
942
933
  "outputs": [],
943
934
  "source": [
@@ -950,7 +941,7 @@
950
941
  {
951
942
  "cell_type": "code",
952
943
  "execution_count": null,
953
- "id": "58",
944
+ "id": "57",
954
945
  "metadata": {},
955
946
  "outputs": [],
956
947
  "source": [
@@ -962,7 +953,7 @@
962
953
  {
963
954
  "cell_type": "code",
964
955
  "execution_count": null,
965
- "id": "59",
956
+ "id": "58",
966
957
  "metadata": {},
967
958
  "outputs": [],
968
959
  "source": [
@@ -972,7 +963,7 @@
972
963
  {
973
964
  "cell_type": "code",
974
965
  "execution_count": null,
975
- "id": "60",
966
+ "id": "59",
976
967
  "metadata": {},
977
968
  "outputs": [],
978
969
  "source": [
@@ -983,7 +974,7 @@
983
974
  {
984
975
  "cell_type": "code",
985
976
  "execution_count": null,
986
- "id": "61",
977
+ "id": "60",
987
978
  "metadata": {},
988
979
  "outputs": [],
989
980
  "source": [
@@ -995,7 +986,7 @@
995
986
  {
996
987
  "cell_type": "code",
997
988
  "execution_count": null,
998
- "id": "62",
989
+ "id": "61",
999
990
  "metadata": {},
1000
991
  "outputs": [],
1001
992
  "source": [
@@ -1008,7 +999,7 @@
1008
999
  {
1009
1000
  "cell_type": "code",
1010
1001
  "execution_count": null,
1011
- "id": "63",
1002
+ "id": "62",
1012
1003
  "metadata": {},
1013
1004
  "outputs": [],
1014
1005
  "source": [
@@ -1022,7 +1013,7 @@
1022
1013
  {
1023
1014
  "cell_type": "code",
1024
1015
  "execution_count": null,
1025
- "id": "64",
1016
+ "id": "63",
1026
1017
  "metadata": {},
1027
1018
  "outputs": [],
1028
1019
  "source": [
@@ -1032,7 +1023,7 @@
1032
1023
  {
1033
1024
  "cell_type": "code",
1034
1025
  "execution_count": null,
1035
- "id": "65",
1026
+ "id": "64",
1036
1027
  "metadata": {},
1037
1028
  "outputs": [],
1038
1029
  "source": []
@@ -1040,7 +1031,7 @@
1040
1031
  {
1041
1032
  "cell_type": "code",
1042
1033
  "execution_count": null,
1043
- "id": "66",
1034
+ "id": "65",
1044
1035
  "metadata": {},
1045
1036
  "outputs": [],
1046
1037
  "source": []
@@ -10,8 +10,9 @@
10
10
  "%%capture\n",
11
11
  "import os\n",
12
12
  "from pathlib import Path\n",
13
- "\n",
13
+ "import pandas as pd\n",
14
14
  "from dj_notebook import activate\n",
15
+ "import numpy as np\n",
15
16
  "\n",
16
17
  "env_file = os.environ[\"META_ENV\"]\n",
17
18
  "reports_folder = Path(os.environ[\"META_REPORTS_FOLDER\"])\n",
@@ -27,19 +28,19 @@
27
28
  "metadata": {},
28
29
  "outputs": [],
29
30
  "source": [
30
- "from edc_pharmacy.models import StockRequestItem, Stock, StockAdjustment\n",
31
- "from django_pandas.io import read_frame\n"
31
+ "from edc_pharmacy.utils import get_stock_for_location_df\n",
32
+ "from edc_pharmacy.models import Location, Stock, Dispense, StockRequest\n",
33
+ "from django.db.models import Count\n",
34
+ "from edc_pharmacy.utils import get_instock_and_nostock_data\n",
35
+ "from edc_pharmacy.analytics import get_next_scheduled_visit_for_subjects_df\n",
36
+ "\n"
32
37
  ]
33
38
  },
34
39
  {
35
- "cell_type": "code",
36
- "execution_count": null,
40
+ "cell_type": "markdown",
37
41
  "id": "2",
38
42
  "metadata": {},
39
- "outputs": [],
40
- "source": [
41
- "Stock.objects.all().order_by(\"created\").last()"
42
- ]
43
+ "source": []
43
44
  },
44
45
  {
45
46
  "cell_type": "code",
@@ -48,8 +49,8 @@
48
49
  "metadata": {},
49
50
  "outputs": [],
50
51
  "source": [
51
- "\n",
52
- "df = read_frame(StockRequestItem.objects.filter(stock_request__request_identifier=\"000122\"))"
52
+ "location = Location.objects.all()[2]\n",
53
+ "get_stock_for_location_df(location)"
53
54
  ]
54
55
  },
55
56
  {
@@ -59,7 +60,17 @@
59
60
  "metadata": {},
60
61
  "outputs": [],
61
62
  "source": [
62
- "df.query(\"in_stock==False\")"
63
+ "\n",
64
+ "qs_stock = (\n",
65
+ " Stock.objects.values(\n",
66
+ " \"allocation__registered_subject__subject_identifier\",\n",
67
+ " \"code\",\n",
68
+ " \"dispense__dispense_identifier\",\n",
69
+ " \"location__name\",\n",
70
+ " )\n",
71
+ " .filter(location=location, qty=1)\n",
72
+ " .annotate(count=Count(\"allocation__registered_subject__subject_identifier\"))\n",
73
+ ")\n"
63
74
  ]
64
75
  },
65
76
  {
@@ -69,7 +80,7 @@
69
80
  "metadata": {},
70
81
  "outputs": [],
71
82
  "source": [
72
- "StockRequestItem.objects.filter(received=True)"
83
+ "qs_stock"
73
84
  ]
74
85
  },
75
86
  {
@@ -79,7 +90,7 @@
79
90
  "metadata": {},
80
91
  "outputs": [],
81
92
  "source": [
82
- "df = read_frame(Stock.objects.filter(from_stock__code=\"UGNXMR\"))\n"
93
+ "Dispense.objects.all()[0].__dict__"
83
94
  ]
84
95
  },
85
96
  {
@@ -89,7 +100,7 @@
89
100
  "metadata": {},
90
101
  "outputs": [],
91
102
  "source": [
92
- "df[df[\"unit_qty_in\"]==0.0]"
103
+ "Stock.objects.filter(dispense__isnull=False)"
93
104
  ]
94
105
  },
95
106
  {
@@ -99,7 +110,10 @@
99
110
  "metadata": {},
100
111
  "outputs": [],
101
112
  "source": [
102
- "df[\"unit_qty_in\"].dtype"
113
+ "stock_request = StockRequest.objects.get(request_identifier=\"000122\")\n",
114
+ "df_next_scheduled_visits = get_next_scheduled_visit_for_subjects_df(stock_request)\n",
115
+ "df_instock, df_nostock = get_instock_and_nostock_data(stock_request, df_next_scheduled_visits)\n",
116
+ "\n"
103
117
  ]
104
118
  },
105
119
  {
@@ -109,7 +123,7 @@
109
123
  "metadata": {},
110
124
  "outputs": [],
111
125
  "source": [
112
- "obj = Stock.objects.get(code=\"UGNXMR\")"
126
+ "df_instock"
113
127
  ]
114
128
  },
115
129
  {
@@ -119,7 +133,7 @@
119
133
  "metadata": {},
120
134
  "outputs": [],
121
135
  "source": [
122
- "obj.__dict__"
136
+ "df_nostock"
123
137
  ]
124
138
  },
125
139
  {
@@ -128,9 +142,7 @@
128
142
  "id": "11",
129
143
  "metadata": {},
130
144
  "outputs": [],
131
- "source": [
132
- "obj.unit_qty_in"
133
- ]
145
+ "source": []
134
146
  },
135
147
  {
136
148
  "cell_type": "code",
@@ -138,9 +150,7 @@
138
150
  "id": "12",
139
151
  "metadata": {},
140
152
  "outputs": [],
141
- "source": [
142
- "obj.unit_qty_out\n"
143
- ]
153
+ "source": []
144
154
  },
145
155
  {
146
156
  "cell_type": "code",
@@ -148,19 +158,7 @@
148
158
  "id": "13",
149
159
  "metadata": {},
150
160
  "outputs": [],
151
- "source": [
152
- "for obj in Stock.objects.filter(container__container_type__name=\"bucket\"):\n",
153
- " obj.save()\n",
154
- " stock_code = obj.code\n",
155
- " stock_unit_qty_in = obj.unit_qty_in\n",
156
- " stock_unit_qty_out = obj.unit_qty_out\n",
157
- " from_stock_count = Stock.objects.filter(from_stock__code=obj.code).count() * 128\n",
158
- " \n",
159
- " \n",
160
- " if not stock_unit_qty_in >= stock_unit_qty_out:\n",
161
- " print(stock_code, stock_unit_qty_in, stock_unit_qty_out, from_stock_count)\n",
162
- " print(f\"**Error stock_code={stock_code}\")"
163
- ]
161
+ "source": []
164
162
  },
165
163
  {
166
164
  "cell_type": "code",
@@ -168,9 +166,7 @@
168
166
  "id": "14",
169
167
  "metadata": {},
170
168
  "outputs": [],
171
- "source": [
172
- "obj"
173
- ]
169
+ "source": []
174
170
  },
175
171
  {
176
172
  "cell_type": "code",
@@ -178,9 +174,7 @@
178
174
  "id": "15",
179
175
  "metadata": {},
180
176
  "outputs": [],
181
- "source": [
182
- "obj_adjustment = StockAdjustment.objects.create(stock=obj, unit_qty_in_old=obj.unit_qty_in, unit_qty_in_new=24576.00)"
183
- ]
177
+ "source": []
184
178
  },
185
179
  {
186
180
  "cell_type": "code",
@@ -188,9 +182,7 @@
188
182
  "id": "16",
189
183
  "metadata": {},
190
184
  "outputs": [],
191
- "source": [
192
- "obj.refresh_from_db()"
193
- ]
185
+ "source": []
194
186
  },
195
187
  {
196
188
  "cell_type": "code",
@@ -199,7 +191,19 @@
199
191
  "metadata": {},
200
192
  "outputs": [],
201
193
  "source": [
202
- "obj.unit_qty_in"
194
+ "from edc_pdutils.dataframes import get_appointments\n",
195
+ "\n",
196
+ "from edc_utils import get_utcnow\n",
197
+ "from edc_appointment.constants import NEW_APPT\n",
198
+ "from dateutil.relativedelta import relativedelta\n",
199
+ "from datetime import datetime\n",
200
+ "\n",
201
+ "df_appt = get_appointments()\n",
202
+ "\n",
203
+ "mask1 = (df_appt.visit_code.isin([1240.0, 1360.0, 1480.0]))\n",
204
+ "mask2 = (df_appt.appt_datetime > datetime(2026, 1, 1)) & (df_appt.appt_datetime < datetime(2026, 8, 1))\n",
205
+ "df = df_appt[(df_appt.appt_status==NEW_APPT) & mask1 & mask2]\n",
206
+ "df.subject_identifier.nunique()\n"
203
207
  ]
204
208
  },
205
209
  {
@@ -209,7 +213,9 @@
209
213
  "metadata": {},
210
214
  "outputs": [],
211
215
  "source": [
212
- "StockAdjustment.objects.all().delete()"
216
+ "\n",
217
+ "df = df_appt[(df_appt.appt_status!=NEW_APPT) & (df_appt.visit_code.isin([1240.0, 1360.0, 1480.0]))].visit_code.value_counts()\n",
218
+ "df.sum()"
213
219
  ]
214
220
  },
215
221
  {
@@ -219,7 +225,8 @@
219
225
  "metadata": {},
220
226
  "outputs": [],
221
227
  "source": [
222
- "obj_adjustment"
228
+ "from tabulate import tabulate\n",
229
+ "print(tabulate(df.to_frame(), headers=\"keys\"))"
223
230
  ]
224
231
  },
225
232
  {
@@ -229,7 +236,8 @@
229
236
  "metadata": {},
230
237
  "outputs": [],
231
238
  "source": [
232
- "obj_adjustment.__dict__"
239
+ "\n",
240
+ "df_appt.appt_datetime < datetime(2025, 12, 1)"
233
241
  ]
234
242
  },
235
243
  {
@@ -397,6 +397,8 @@ EDC_LABEL_BROWSER_PRINT_PAGE_AUTO_BACK = env("EDC_LABEL_BROWSER_PRINT_PAGE_AUTO_
397
397
 
398
398
  # edc_model_admin
399
399
  EDC_MODEL_ADMIN_CSS_THEME = "edc_indigo"
400
+ EDC_MODEL_ADMIN_SAVE_DELAY = 3000
401
+
400
402
  # edc-mnsi
401
403
  EDC_MNSI_MODEL = "meta_subject.mnsi"
402
404
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meta-edc
3
- Version: 1.1.4
3
+ Version: 1.1.5
4
4
  Summary: META Trial EDC (http://www.isrctn.com/ISRCTN76157257)
5
5
  Home-page: https://github.com/meta-trial/meta-edc
6
6
  Author: Erik van Widenfelt
@@ -694,7 +694,7 @@ Requires-Python: >=3.12
694
694
  Description-Content-Type: text/x-rst
695
695
  License-File: LICENSE
696
696
  License-File: AUTHORS.rst
697
- Requires-Dist: edc==1.1.3
697
+ Requires-Dist: edc==1.1.4
698
698
  Requires-Dist: beautifulsoup4
699
699
  Requires-Dist: celery[redis]
700
700
  Requires-Dist: django-pylabels
@@ -111,9 +111,9 @@ meta_analytics/notebooks/incidence.ipynb,sha256=-kd0Mp67dk8ECoNEcKMTn92iBxuNLBIO
111
111
  meta_analytics/notebooks/liver.ipynb,sha256=s19AAV6vmtGqYAfN1cqVIcBeU7ptSGU94uZaeaz32qU,13985
112
112
  meta_analytics/notebooks/magreth.ipynb,sha256=u4BWz6swBFLXcrOQDi_iSuFkp9NiISFk5uPahh7iXug,20773
113
113
  meta_analytics/notebooks/monitoring_report.ipynb,sha256=BySeKJZ7MQPGQ6vbNNXW5JBJyNmTfvP_c8JGjskUF5U,77415
114
- meta_analytics/notebooks/pharmacy.ipynb,sha256=rAxMyPDZIyx-Qizgrdueq-rUYyeN3zMYVqDPkbjtnSs,34298
114
+ meta_analytics/notebooks/pharmacy.ipynb,sha256=LxV425ixFqiZin7wEeTnbPGNhX6jkkeVB3jozF_pir0,34182
115
115
  meta_analytics/notebooks/pharmacy_stock_202410.ipynb,sha256=Kx9QVmiDW-5DWuaoSvLM2vJGHRCam-im9ZVdJsOBFfs,8823
116
- meta_analytics/notebooks/qa.ipynb,sha256=QuAoepwpC1nQLYC-HWM6khNIsPDU_s13gk1Iz2RjETk,5282
116
+ meta_analytics/notebooks/qa.ipynb,sha256=W1pbk-CFArP6oyVUU522NVuenPcSKm5-Mj9rf_DCdjo,5983
117
117
  meta_analytics/notebooks/steering.ipynb,sha256=pqJrH_Zdwp7sPgHwhahKK-XmNMQjk7bHJv7vHJaeTek,1112
118
118
  meta_analytics/notebooks/ven.ipynb,sha256=JR1_BW2QGqsqteCSORS7Zz7yD3u8JeU9r4H7KJ6nRN4,5182
119
119
  meta_analytics/notebooks/vitals.ipynb,sha256=mHlO6QbhD28aGUhVI0tF06MJm_JjUsKLdSpnz5NhbQI,5787
@@ -278,7 +278,7 @@ meta_edc/management/commands/update_forms_reference.py,sha256=jvCU9YdMtp9wbmjqKQ
278
278
  meta_edc/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
279
279
  meta_edc/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
280
280
  meta_edc/settings/debug.py,sha256=4BkeyJuOq3b_TJJr18tgoYSM7LZgnlz7CmJhTFiEt14,1297
281
- meta_edc/settings/defaults.py,sha256=USh91oF6HKdUXWZ5xf5dDCwAYINSIdOPkgHCxDCsGP4,19633
281
+ meta_edc/settings/defaults.py,sha256=S5y44_9LrFx7BEPMOlrSUpiFDldgsnt-VfgERYAvQBU,19668
282
282
  meta_edc/settings/live.py,sha256=uLTlsIc3H6gdE_7pkL6vyOVa6V_74hnXFkiojqGFAYY,264
283
283
  meta_edc/settings/logging.py,sha256=6qVUE37OMkf5rzwTmMq4krFsZ2jcyCpWdFtGih_Cs4U,1938
284
284
  meta_edc/settings/minimal.py,sha256=3z-7GBluflnUkuSotKZlYvpL34NZ6tfFNuQNJLCyflo,592
@@ -290,8 +290,8 @@ meta_edc/tests/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
290
290
  meta_edc/tests/tests/test_endpoints.py,sha256=5FdIHTd1xhUIgQLBzMV-Ml3VoFrlBrLLUbNarme5raw,23541
291
291
  meta_edc/views/__init__.py,sha256=TBXTih4Mpsg5Oh2jbyXqL9kH7bu3vWNRgVe93hvLCl8,32
292
292
  meta_edc/views/home_view.py,sha256=BXydy77TcdcM0-R3S_uHI4DtfnLMIzPJMyqjFJZFSsA,916
293
- meta_edc-1.1.4.dist-info/licenses/AUTHORS.rst,sha256=wL4KUOd7FAFThhkLAJxSLQ2BPzd3ikG9q0UVZr3BbLg,244
294
- meta_edc-1.1.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
293
+ meta_edc-1.1.5.dist-info/licenses/AUTHORS.rst,sha256=wL4KUOd7FAFThhkLAJxSLQ2BPzd3ikG9q0UVZr3BbLg,244
294
+ meta_edc-1.1.5.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
295
295
  meta_export/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
296
296
  meta_export/admin_site.py,sha256=CiKAf0gDFvBKVc-1VM6KwM905ayVZuiY1tgaTeUeCi0,167
297
297
  meta_export/apps.py,sha256=3_5LB1MLtzfKekI2vT9Cm6puAx6t6AjtIfTTVdItdKg,226
@@ -480,12 +480,14 @@ meta_prn/migrations/0061_auto_20250115_2025.py,sha256=u7F2GsXo-9pIN5z0VM1aXW_KoR
480
480
  meta_prn/migrations/0062_alter_endofstudy_offstudy_reason_and_more.py,sha256=L1ZDX1IMS0nIs77lF4QZ0SX-ye4rXvouTLnijob8SAQ,2421
481
481
  meta_prn/migrations/0063_historicaloffstudymedication_singleton_field_and_more.py,sha256=l8pNm7G0O_7hWMb7smU5wbbsjE7es-WZfCkET7zyuXw,1081
482
482
  meta_prn/migrations/0064_auto_20250602_2143.py,sha256=S8-7kSWfJSFtzKrq5_puYIC0UA32wRZH_-xnQ6mt--w,512
483
+ meta_prn/migrations/0065_alter_historicaloffstudymedication_subject_identifier_and_more.py,sha256=doqlcfQv6n4N89i4wZrXm48ZCpdr_iuV_llrhp8RJDk,626
484
+ meta_prn/migrations/0066_alter_historicallosstofollowup_subject_identifier_and_more.py,sha256=hUTNf3oiIxJODNXXwjTeVZS-xEMBsCn3XyR2aPcfO7o,662
483
485
  meta_prn/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
484
486
  meta_prn/models/__init__.py,sha256=l06P7L2_Aye2h2VmAyb1XRcIbQAOyxws08IMc8sIops,717
485
487
  meta_prn/models/dm_referral.py,sha256=XyyB5ylcaMRCumGRFPlh2Op5VvT9ROJ1A9x5q55vUuc,1096
486
488
  meta_prn/models/end_of_study.py,sha256=wg2Y8Q_via6GozskaCzqkky_jOrtSLNek77-X2KLJME,5444
487
- meta_prn/models/loss_to_followup.py,sha256=qo2RrK5cVC1wLE7DdE6rTCCtYn7iAMomov9IbSCFuWg,2397
488
- meta_prn/models/off_study_medication.py,sha256=7PzUkyrBWTybTWcNMU5EioApbOoiIaUDnCiEcjgX-II,1779
489
+ meta_prn/models/loss_to_followup.py,sha256=FxWMsZmwGaL7SHnjFOUhsbWoG3bauLdEAAT0ZNNUd-g,2391
490
+ meta_prn/models/off_study_medication.py,sha256=K_pzeJ62z-01dWR0JrUVO0Bm0L7T0RCeSzYt9wBk0nE,1773
489
491
  meta_prn/models/offschedule.py,sha256=DjQvXteecXJOzN6ijdH36FCxXoR1halzxl9EliqQJk8,1717
490
492
  meta_prn/models/onschedule.py,sha256=xAlKzvcM5VzVfzaayjUEvUSL6rsALQQSm9iFCs1rnWc,930
491
493
  meta_prn/models/pregnancy_notification.py,sha256=HqRsonJ0F1nxLczVtgPkvGb7kWQOkJDz3w67jOxi5j4,3090
@@ -773,7 +775,7 @@ meta_screening/models/subject_screening.py,sha256=j-0U5zcErwEv0qYEn9ktaPiNfce-CF
773
775
  meta_screening/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
774
776
  meta_screening/tests/holidays.csv,sha256=Ywr5pK_caGUJMgRwLzjMeSEUuyEpUWyJE5aJkfbg3bg,539
775
777
  meta_screening/tests/meta_test_case_mixin.py,sha256=dBdYp1U9mW9J7ghrgchXOOWeZPhiVcQ09mV3GHbiors,8949
776
- meta_screening/tests/options.py,sha256=VpRQWWPwlVUReFi4KHuJdHXTBCsWvR2IlHs4yTDxQVA,4097
778
+ meta_screening/tests/options.py,sha256=7cpbOeyyQIfw9sja94Y7fwI0XRgRustK7VE8rDT9s6I,4125
777
779
  meta_screening/tests/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
778
780
  meta_screening/tests/tests/test_forms.py,sha256=wTR3fe4-v6L5sw_eApdcCn6xnu_I6Q6fpOIZlUVvcXA,16903
779
781
  meta_screening/tests/tests/test_screening_part_one.py,sha256=EyG3SRVpR6-bFB0bn9UEA4hL8638e-Kx7K0_AeaBntE,4723
@@ -813,7 +815,7 @@ meta_subject/admin/egfr_drop_notification_admin.py,sha256=xXGHIMmVnFpNClEMX3i6dZ
813
815
  meta_subject/admin/eq5d3l_admin.py,sha256=NB_DwtEA4PNnoxXqXdfnMYqUDVjwOaRtNOsIbzZalPg,772
814
816
  meta_subject/admin/fields.py,sha256=-be67ToKIOHOmytxR9qsEAucbDEFWyFySmG_VoIrRn4,277
815
817
  meta_subject/admin/fieldsets.py,sha256=nds9nLPscsaETET-bxX94AsBGZ6npQk_4POz8oex6jc,1523
816
- meta_subject/admin/followup_examination_admin.py,sha256=3tcD6dVkAh0bsNkJE1iSmNoiM4G6h0mkAySxlHpN9MA,5153
818
+ meta_subject/admin/followup_examination_admin.py,sha256=_w8Mds3K0JajsMa7stKRKdJM-QidPu_k-ZKWX1805TA,5154
817
819
  meta_subject/admin/followup_vitals_admin.py,sha256=dvpU5tR-_5YeB5_HHrP8-DwQ7Z6j9tgCsyP5Bn3yM3M,1585
818
820
  meta_subject/admin/glucose_admin.py,sha256=IBKJp-tgeIZUObmanL8UPtZWQHsUiOl3raBqesh0MJU,2981
819
821
  meta_subject/admin/glucose_fbg_admin.py,sha256=GsXp5vIzgEt355qyXYr5QhWkGZdOzXzX-ZPOWAHmGlU,2492
@@ -1239,7 +1241,7 @@ tests/etc/user-rsa-restricted-private.pem,sha256=CUcHW9bznWdmmASN00hCzvxFPAFl4N2
1239
1241
  tests/etc/user-rsa-restricted-public.pem,sha256=mt84djoL-uHw6Wc5SJh0zml6VzXulnf8eQSFg7-fheg,450
1240
1242
  tests/etc/user-salt-local.key,sha256=x5anBw9fvbHurczouT3CjrkWb_xs7Ypm1htIJsgiuiw,256
1241
1243
  tests/etc/user-salt-restricted.key,sha256=pxmpcfBRNB-4C6wTvHXz-9fOfJgKIFOjaAF8ZFfa4q4,256
1242
- meta_edc-1.1.4.dist-info/METADATA,sha256=1Hmz3EzYTnUjBxiMeWf4N79io4K92wupe-48_bIrfqM,43587
1243
- meta_edc-1.1.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1244
- meta_edc-1.1.4.dist-info/top_level.txt,sha256=RkzjNXwRq2kg_uZ_1bDwPUntijSXoY2YBqtByDwvvrc,244
1245
- meta_edc-1.1.4.dist-info/RECORD,,
1244
+ meta_edc-1.1.5.dist-info/METADATA,sha256=tGv9WuDrOcQPZYvqP1TGT2_RodSMFYL3Vcbtz4Eg2gY,43587
1245
+ meta_edc-1.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1246
+ meta_edc-1.1.5.dist-info/top_level.txt,sha256=RkzjNXwRq2kg_uZ_1bDwPUntijSXoY2YBqtByDwvvrc,244
1247
+ meta_edc-1.1.5.dist-info/RECORD,,
@@ -0,0 +1,23 @@
1
+ # Generated by Django 5.2.3 on 2025-07-03 22:44
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ("meta_prn", "0064_auto_20250602_2143"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name="historicaloffstudymedication",
15
+ name="subject_identifier",
16
+ field=models.CharField(db_index=True, max_length=50),
17
+ ),
18
+ migrations.AlterField(
19
+ model_name="offstudymedication",
20
+ name="subject_identifier",
21
+ field=models.CharField(max_length=50, unique=True),
22
+ ),
23
+ ]
@@ -0,0 +1,23 @@
1
+ # Generated by Django 5.2.3 on 2025-07-03 22:46
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ("meta_prn", "0065_alter_historicaloffstudymedication_subject_identifier_and_more"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name="historicallosstofollowup",
15
+ name="subject_identifier",
16
+ field=models.CharField(db_index=True, max_length=50),
17
+ ),
18
+ migrations.AlterField(
19
+ model_name="losstofollowup",
20
+ name="subject_identifier",
21
+ field=models.CharField(max_length=50, unique=True),
22
+ ),
23
+ ]
@@ -2,7 +2,7 @@ from django.db import models
2
2
  from edc_action_item.models.action_model_mixin import ActionModelMixin
3
3
  from edc_constants.choices import YES_NO
4
4
  from edc_constants.constants import OTHER
5
- from edc_identifier.model_mixins import NonUniqueSubjectIdentifierFieldMixin
5
+ from edc_identifier.model_mixins import UniqueSubjectIdentifierFieldMixin
6
6
  from edc_ltfu.constants import LTFU_ACTION
7
7
  from edc_model.models import BaseUuidModel, OtherCharField
8
8
  from edc_sites.model_mixins import SiteModelMixin
@@ -19,7 +19,7 @@ LOSS_CHOICES = (
19
19
  class LossToFollowup(
20
20
  ActionModelMixin,
21
21
  SiteModelMixin,
22
- NonUniqueSubjectIdentifierFieldMixin,
22
+ UniqueSubjectIdentifierFieldMixin,
23
23
  BaseUuidModel,
24
24
  ):
25
25
  action_name = LTFU_ACTION
@@ -1,6 +1,6 @@
1
1
  from django.db import models
2
2
  from edc_action_item.models import ActionModelMixin
3
- from edc_identifier.model_mixins import NonUniqueSubjectIdentifierFieldMixin
3
+ from edc_identifier.model_mixins import UniqueSubjectIdentifierFieldMixin
4
4
  from edc_model.models import BaseUuidModel
5
5
  from edc_pharmacy.models import Medication
6
6
  from edc_prn.models import SingletonPrnModelMixin
@@ -14,7 +14,7 @@ from ..constants import OFFSTUDY_MEDICATION_ACTION
14
14
 
15
15
 
16
16
  class OffStudyMedication(
17
- NonUniqueSubjectIdentifierFieldMixin,
17
+ UniqueSubjectIdentifierFieldMixin,
18
18
  SiteModelMixin,
19
19
  ActionModelMixin,
20
20
  SingletonPrnModelMixin,
@@ -34,8 +34,8 @@ def get_part_one_eligible_options():
34
34
  ethnicity=BLACK,
35
35
  gender=FEMALE,
36
36
  hiv_pos=YES,
37
- hospital_identifier="".join(map(str, sample(range(0, 10), 10))),
38
- initials=f"{choice(ascii_uppercase)}{choice(ascii_uppercase)}",
37
+ hospital_identifier="".join(map(str, sample(range(0, 10), 10))), # nosec B311
38
+ initials=f"{choice(ascii_uppercase)}{choice(ascii_uppercase)}", # nosec B311
39
39
  lives_nearby=YES,
40
40
  on_rx_stable=YES,
41
41
  pregnant=NOT_APPLICABLE,
@@ -36,6 +36,7 @@ class FollowupExaminationAdmin(
36
36
  ActionItemModelAdminMixin,
37
37
  SimpleHistoryAdmin,
38
38
  ):
39
+
39
40
  form = FollowupExaminationForm
40
41
 
41
42
  autocomplete_fields = ["art_new_regimen"]