diff --git a/backend/apps/fields/urls.py b/backend/apps/fields/urls.py index a071d2d..7f31e37 100644 --- a/backend/apps/fields/urls.py +++ b/backend/apps/fields/urls.py @@ -9,4 +9,5 @@ urlpatterns = [ path('', include(router.urls)), path('import/kyosai/', views.import_kyosai_master, name='import_kyosai'), path('import/yoshida/', views.import_yoshida_fields, name='import_yoshida'), + path('import/chusankan/', views.import_chusankan_master, name='import_chusankan'), ] diff --git a/backend/apps/fields/views.py b/backend/apps/fields/views.py index e7bd8cb..58824cb 100644 --- a/backend/apps/fields/views.py +++ b/backend/apps/fields/views.py @@ -112,18 +112,13 @@ def import_yoshida_fields(request): else: updated_count += 1 - if raw_kyosai_k: + if raw_kyosai_k and raw_kyosai_s: try: - kyosai_record = OfficialKyosaiField.objects.get(k_num=raw_kyosai_k) + kyosai_record = OfficialKyosaiField.objects.get(k_num=raw_kyosai_k, s_num=raw_kyosai_s) 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: + except OfficialKyosaiField.MultipleObjectsReturned: pass if raw_chusankan: @@ -142,3 +137,53 @@ def import_yoshida_fields(request): except Exception as e: return JsonResponse({'error': str(e)}, status=500) + + +@csrf_exempt +@require_http_methods(["POST"]) +def import_chusankan_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') + df.columns = df.columns.str.strip() + + created_count = 0 + updated_count = 0 + + for _, row in df.iterrows(): + c_id = str(row.get('ID', '')).strip() if pd.notna(row.get('ID')) else '' + + if not c_id: + continue + + defaults = { + 'oaza': str(row.get('大字', '')).strip() if pd.notna(row.get('大字')) else '', + 'aza': str(row.get('字', '')).strip() if pd.notna(row.get('字')) else '', + 'chiban': str(row.get('地番', '')).strip() if pd.notna(row.get('地番')) else '', + 'area': float(row.get('農地面積', 0)) if pd.notna(row.get('農地面積')) else 0, + 'payment_amount': int(row.get('交付金額', 0)) if pd.notna(row.get('交付金額')) else None, + } + + obj, created = OfficialChusankanField.objects.update_or_create( + c_id=c_id, + 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)