-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0b6f61e
commit 740d142
Showing
33 changed files
with
286 additions
and
308 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
..._workspace/contrib/kobo/raw/asset_list.py → ...kspace/contrib/kobo/api/raw/asset_list.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
...space/contrib/kobo/raw/submission_list.py → ...e/contrib/kobo/api/raw/submission_list.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from django import forms | ||
|
||
from country_workspace.contrib.kobo.models import KoboAsset | ||
|
||
|
||
class ImportKoboAssetsForm(forms.Form): | ||
batch_name = forms.CharField(required=False, help_text="Label for this batch") | ||
|
||
|
||
class ImportKoboDataForm(forms.Form): | ||
batch_name = forms.CharField(required=False, help_text="Label for this batch") | ||
individual_records_field = forms.CharField( | ||
required=False, | ||
initial="individual_questions", | ||
help_text="Which field contains individual records", | ||
) | ||
assets = forms.ModelMultipleChoiceField( | ||
widget=forms.CheckboxSelectMultiple, | ||
queryset=KoboAsset.objects.all(), | ||
help_text="Which assets should be imported", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from django.db import models | ||
|
||
from country_workspace.models import Program | ||
|
||
|
||
class KoboAsset(models.Model): | ||
uid = models.CharField(primary_key=True, max_length=32, editable=False) | ||
name = models.CharField(max_length=128, null=True, editable=False) | ||
programs = models.ManyToManyField(Program) | ||
|
||
def __str__(self) -> str: | ||
return self.name or "No name" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from constance import config | ||
|
||
from country_workspace.contrib.kobo.api.client import Client as KoboClient | ||
from country_workspace.models import AsyncJob, KoboAsset, Batch, Individual | ||
from country_workspace.utils.fields import clean_field_name | ||
|
||
|
||
def sync_assets(_: AsyncJob) -> dict[str, int]: | ||
client = KoboClient(base_url=config.KOBO_BASE_URL, token=config.KOBO_TOKEN) | ||
created_assets = 0 | ||
updated_assets = 0 | ||
for asset in client.assets: | ||
asset_model, created = KoboAsset.objects.update_or_create(uid=asset.uid, defaults={"name": asset.name}) | ||
if created: | ||
created_assets += 1 | ||
else: | ||
updated_assets += 1 | ||
|
||
return {"created": created_assets, "updated": updated_assets} | ||
|
||
|
||
def sync_data(job: AsyncJob) -> dict[str, int]: | ||
batch = Batch.objects.create( | ||
name=job.config["batch_name"], | ||
program=job.program, | ||
country_office=job.program.country_office, | ||
imported_by=job.owner, | ||
source=Batch.BatchSource.KOBO, | ||
) | ||
individual_records_field = job.config["individual_records_field"] | ||
client = KoboClient(base_url=config.KOBO_BASE_URL, token=config.KOBO_TOKEN) | ||
assets = (asset for asset in client.assets if asset.uid in job.config["assets"]) | ||
for asset in assets: | ||
for submission in asset.submissions: | ||
household_fields = {key: value for key, value in submission if key != individual_records_field} | ||
household = batch.program.households.create(batch=batch, flex_fields={clean_field_name(key): value for key, value in household_fields.items()}) | ||
individuals = [] | ||
for individual in submission[individual_records_field]: | ||
fullname = next((key for key in individual if key.startswith("given_name")), None) | ||
individuals.append( | ||
Individual( | ||
batch=batch, | ||
household_id=household.pk, | ||
name=individual.get(fullname, ""), | ||
flex_fields={clean_field_name(key): value for key, value in individual.items()}, | ||
), | ||
) | ||
return {"households": 0, "individuals": 0} |
65 changes: 65 additions & 0 deletions
65
src/country_workspace/migrations/0002_alter_program_active_and_more.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# Generated by Django 5.1.3 on 2025-01-02 04:09 | ||
|
||
import django.db.models.deletion | ||
import strategy_field.fields | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("country_workspace", "0001_initial"), | ||
("hope_flex_fields", "0013_fielddefinition_validated_alter_datachecker_id_and_more"), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterField( | ||
model_name="program", | ||
name="active", | ||
field=models.BooleanField( | ||
default=False, help_text="Whether the program is active. Only active program are visible in the UI" | ||
), | ||
), | ||
migrations.AlterField( | ||
model_name="program", | ||
name="beneficiary_validator", | ||
field=strategy_field.fields.StrategyField( | ||
blank=True, | ||
default="country_workspace.validators.registry.NoopValidator", | ||
help_text="Validator to use to validate the whole Household", | ||
null=True, | ||
), | ||
), | ||
migrations.AlterField( | ||
model_name="program", | ||
name="household_checker", | ||
field=models.ForeignKey( | ||
blank=True, | ||
help_text="Checker to use with Household's records", | ||
null=True, | ||
on_delete=django.db.models.deletion.CASCADE, | ||
related_name="+", | ||
to="hope_flex_fields.datachecker", | ||
), | ||
), | ||
migrations.AlterField( | ||
model_name="program", | ||
name="individual_checker", | ||
field=models.ForeignKey( | ||
blank=True, | ||
help_text="Checker to use with Individual's records", | ||
null=True, | ||
on_delete=django.db.models.deletion.CASCADE, | ||
related_name="+", | ||
to="hope_flex_fields.datachecker", | ||
), | ||
), | ||
migrations.CreateModel( | ||
name="KoboAsset", | ||
fields=[ | ||
("uid", models.CharField(editable=False, max_length=32, primary_key=True, serialize=False)), | ||
("name", models.CharField(editable=False, max_length=128, null=True)), | ||
("programs", models.ManyToManyField(to="country_workspace.program")), | ||
], | ||
), | ||
] |
Oops, something went wrong.