from flask import request, jsonify, render_template from flask_login import current_user from app import db from app.models import Task, WorkDetail from app.service.logger import log_activity def recalc_task(task): rate = float(task.rate or 0) qty = float(task.qty or 0) prev_qty = float(task.previous_billed_qty or 0) ra_qty = float(task.in_this_ra_bill_qty or 0) # H = G * E task.previous_billing_amount = round(prev_qty * rate, 2) # J = I * E task.in_this_ra_billing_amount = round(ra_qty * rate, 2) # K = I + G task.cumulative_billed_qty = round(prev_qty + ra_qty, 2) # L = K * E task.cumulative_billed_amount = round(task.cumulative_billed_qty * rate, 2) # M = IF(K > D , K - D , 0) if task.cumulative_billed_qty > qty: task.variation_qty = round(task.cumulative_billed_qty - qty, 2) else: task.variation_qty = 0 # N = M * E task.variation_amount = round(task.variation_qty * rate, 2) # def update_tasks_controller(): # try: # updates = request.get_json() # update_count = 0 # formula_fields = [ # "previous_billing_amount", # "in_this_ra_billing_amount", # "cumulative_billed_qty", # "cumulative_billed_amount", # "variation_qty", # "variation_amount" # ] # for key, new_value in updates.items(): # if '_' not in key: # continue # field_name, task_id_str = key.rsplit('_', 1) # if not task_id_str.isdigit(): # continue # task = Task.query.get(int(task_id_str)) # if task: # if field_name in formula_fields: # continue # current_value = getattr(task, field_name, None) # if str(current_value) != str(new_value): # setattr(task, field_name, new_value) # recalc_task(task) # update_count += 1 # log_activity( # current_user.username, # "Task Update", # f"Task ID {task.id} - {field_name} changed to {new_value}" # ) # if update_count > 0: # db.session.commit() # log_activity( # current_user.username, # "Database Commit", # f"{update_count} task field(s) updated" # ) # return jsonify({'message': f'count: {update_count} field(s) updated.'}) # return jsonify({'message': 'No fields were updated.'}) # except Exception as e: # log_activity(current_user.username, "Error", str(e)) # return jsonify({'error': 'Update failed'}), 500 def update_tasks_controller(): try: updates = request.get_json() update_count = 0 formula_fields = [ "previous_billing_amount", "in_this_ra_billing_amount", "cumulative_billed_qty", "cumulative_billed_amount", "variation_qty", "variation_amount" ] numeric_fields = [ "qty","rate","boq_amount", "previous_billed_qty", "in_this_ra_bill_qty" ] for key, new_value in updates.items(): if '_' not in key: continue field_name, task_id_str = key.rsplit('_', 1) if not task_id_str.isdigit(): continue task = Task.query.get(int(task_id_str)) if task: # Skip formula fields if field_name in formula_fields: continue current_value = getattr(task, field_name, None) # Convert numeric fields if field_name in numeric_fields: try: new_value = float(new_value) if new_value != "" else 0 except: new_value = 0 # Update only if changed if str(current_value) != str(new_value): setattr(task, field_name, new_value) # Recalculate formulas recalc_task(task) update_count += 1 log_activity( current_user.username, "Task Update", f"Task ID {task.id} - {field_name} changed to {new_value}" ) if update_count > 0: db.session.commit() log_activity( current_user.username, "Database Commit", f"{update_count} task field(s) updated" ) return jsonify({'message': f'count: {update_count} field(s) updated.'}) return jsonify({'message': 'No fields were updated.'}) except Exception as e: log_activity(current_user.username, "Error", str(e)) return jsonify({'error': 'Update failed'}), 500 def display_tasks_controller(): work_details = WorkDetail.query.order_by( WorkDetail.uploaded_at.desc() ).first() if not work_details: log_activity(current_user.username, "Tasks View", "No work details") return "No work details available.", 404 tasks = Task.query.filter_by( district=work_details.district, village_name=work_details.name_of_village, block_name=work_details.block ).order_by(Task.uploaded_at.desc()).all() grouped_tasks = [] current_main_task = None for task in tasks: task_data = { "id": task.id, "task_name": task.task_name, "unit": task.unit, "qty": task.qty, "rate": task.rate, "boq_amount": task.boq_amount, "previous_billed_qty": task.previous_billed_qty, "previous_billing_amount": task.previous_billing_amount, "in_this_ra_bill_qty": task.in_this_ra_bill_qty, "in_this_ra_billing_amount": task.in_this_ra_billing_amount, "cumulative_billed_qty": task.cumulative_billed_qty, "cumulative_billed_amount": task.cumulative_billed_amount, "variation_qty": task.variation_qty, "variation_amount": task.variation_amount, "remark": task.remark, "district": task.district } if task.serial_number: task_data["subtasks"] = [] grouped_tasks.append(task_data) current_main_task = task_data elif current_main_task: current_main_task["subtasks"].append(task_data) log_activity( current_user.username, "Tasks View", f"{work_details.name_of_village}, {work_details.block}" ) return render_template( 'tasks_display.html', work_details=work_details, grouped_tasks=grouped_tasks )