diff --git a/backend/apps/fields/urls.py b/backend/apps/fields/urls.py new file mode 100644 index 0000000..1b0bc3f --- /dev/null +++ b/backend/apps/fields/urls.py @@ -0,0 +1,7 @@ +from django.urls import path +from . import views + +urlpatterns = [ + path('import/kyosai/', views.import_kyosai_master, name='import_kyosai'), + path('import/yoshida/', views.import_yoshida_fields, name='import_yoshida'), +] diff --git a/backend/apps/fields/views.py b/backend/apps/fields/views.py index 91ea44a..a4379bd 100644 --- a/backend/apps/fields/views.py +++ b/backend/apps/fields/views.py @@ -1,3 +1,133 @@ -from django.shortcuts import render +import pandas as pd +from django.http import JsonResponse +from django.views.decorators.csrf import csrf_exempt +from django.views.decorators.http import require_http_methods +from .models import OfficialKyosaiField, OfficialChusankanField, Field -# Create your views here. + +@csrf_exempt +@require_http_methods(["POST"]) +def import_kyosai_master(request): + if 'file' not in request.FILES: + return JsonResponse({'error': 'No file uploaded'}, status=400) + + ods_file = request.FILES['file'] + + try: + df = pd.read_excel(ods_file, engine='odf') + + created_count = 0 + updated_count = 0 + + for _, row in df.iterrows(): + k_num = str(row.get('k_num', '')).strip() if pd.notna(row.get('k_num')) else '' + s_num = str(row.get('s_num', '')).strip() if pd.notna(row.get('s_num')) else '' + + if not k_num: + continue + + defaults = { + 's_num': s_num, + 'address': str(row.get('address', '')).strip() if pd.notna(row.get('address')) else '', + 'kanji_name': str(row.get('kanji_name', '')).strip() if pd.notna(row.get('kanji_name')) else '', + 'area': float(row.get('area', 0)) if pd.notna(row.get('area')) else 0, + } + + obj, created = OfficialKyosaiField.objects.update_or_create( + k_num=k_num, + defaults=defaults + ) + + if created: + created_count += 1 + else: + updated_count += 1 + + return JsonResponse({ + 'success': True, + 'created': created_count, + 'updated': updated_count, + 'message': f'共済マスタ: {created_count}件作成, {updated_count}件更新' + }) + + except Exception as e: + return JsonResponse({'error': str(e)}, status=500) + + +@csrf_exempt +@require_http_methods(["POST"]) +def import_yoshida_fields(request): + if 'file' not in request.FILES: + return JsonResponse({'error': 'No file uploaded'}, status=400) + + ods_file = request.FILES['file'] + + try: + df = pd.read_excel(ods_file, engine='odf') + + created_count = 0 + updated_count = 0 + + for _, row in df.iterrows(): + name = str(row.get('name', '')).strip() if pd.notna(row.get('name')) else '' + + if not name: + continue + + raw_kyosai_k = str(int(row.get('raw_kyosai_k_num', 0))) if pd.notna(row.get('raw_kyosai_k_num')) else None + raw_kyosai_s = str(int(row.get('raw_kyosai_s_num', 0))) if pd.notna(row.get('raw_kyosai_s_num')) else None + raw_chusankan = str(int(row.get('raw_chusankan_id', 0))) if pd.notna(row.get('raw_chusankan_id')) else None + + area_tan = float(row.get('area_tan', 0)) if pd.notna(row.get('area_tan')) else 0 + area_m2 = int(row.get('area_m2', 0)) if pd.notna(row.get('area_m2')) else 0 + + defaults = { + 'address': str(row.get('address', '')).strip() if pd.notna(row.get('address')) else '', + 'area_tan': area_tan, + 'area_m2': area_m2, + 'owner_name': str(row.get('owner_name', '')).strip() if pd.notna(row.get('owner_name')) else '', + 'raw_kyosai_k_num': raw_kyosai_k, + 'raw_kyosai_s_num': raw_kyosai_s, + 'raw_chusankan_id': raw_chusankan, + } + + field, created = Field.objects.update_or_create( + name=name, + defaults=defaults + ) + + if created: + created_count += 1 + else: + updated_count += 1 + + if raw_kyosai_k: + try: + kyosai_record = OfficialKyosaiField.objects.get(k_num=raw_kyosai_k) + field.kyosai_fields.add(kyosai_record) + except OfficialKyosaiField.DoesNotExist: + pass + + if raw_kyosai_s: + try: + kyosai_record = OfficialKyosaiField.objects.get(s_num=raw_kyosai_s) + field.kyosai_fields.add(kyosai_record) + except OfficialKyosaiField.DoesNotExist: + pass + + if raw_chusankan: + try: + chusankan_record = OfficialChusakanField.objects.get(c_id=raw_chusankan) + field.chusankan_fields.add(chusankan_record) + except OfficialChusankanField.DoesNotExist: + pass + + return JsonResponse({ + 'success': True, + 'created': created_count, + 'updated': updated_count, + 'message': f'実圃場: {created_count}件作成, {updated_count}件更新' + }) + + except Exception as e: + return JsonResponse({'error': str(e)}, status=500) diff --git a/backend/keinasystem/urls.py b/backend/keinasystem/urls.py index 9f99a94..5e161fa 100644 --- a/backend/keinasystem/urls.py +++ b/backend/keinasystem/urls.py @@ -15,8 +15,9 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path +from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), + path('api/fields/', include('apps.fields.urls')), ]