import os file_path = 'core/views.py' # New Implementations edit_invoice_code = """ @login_required def edit_invoice(request, pk): sale = get_object_or_404(Sale, pk=pk) customers = Customer.objects.all() products = Product.objects.filter(is_active=True).select_related('category') payment_methods = PaymentMethod.objects.filter(is_active=True) site_settings = SystemSetting.objects.first() decimal_places = 2 if site_settings: decimal_places = site_settings.decimal_places # Serialize items for Vue cart_items = [] for item in sale.items.all().select_related('product'): cart_items.append({ 'id': item.product.id, 'name_en': item.product.name_en, 'name_ar': item.product.name_ar, 'sku': item.product.sku, 'price': float(item.unit_price), 'quantity': float(item.quantity), 'stock': float(item.product.stock_quantity) }) cart_json = json.dumps(cart_items) # Get first payment method if exists payment_method_id = "" first_payment = sale.payments.first() if first_payment and first_payment.payment_method: payment_method_id = first_payment.payment_method.id context = { 'sale': sale, 'customers': customers, 'products': products, 'payment_methods': payment_methods, 'site_settings': site_settings, 'decimal_places': decimal_places, 'cart_json': cart_json, 'payment_method_id': payment_method_id } return render(request, 'core/invoice_edit.html', context) """ sale_receipt_code = """ @login_required def sale_receipt(request, pk): sale = get_object_or_404(Sale, pk=pk) settings = SystemSetting.objects.first() return render(request, 'core/sale_receipt.html', { 'sale': sale, 'settings': settings }) """ update_sale_api_code = """ @csrf_exempt def update_sale_api(request, pk): if request.method != 'POST': return JsonResponse({'success': False, 'error': 'Invalid request method'}) try: sale = Sale.objects.get(pk=pk) data = json.loads(request.body) customer_id = data.get('customer_id') items = data.get('items', []) discount = decimal.Decimal(str(data.get('discount', 0))) paid_amount = decimal.Decimal(str(data.get('paid_amount', 0))) payment_type = data.get('payment_type', 'cash') payment_method_id = data.get('payment_method_id') due_date = data.get('due_date') notes = data.get('notes', '') invoice_number = data.get('invoice_number') if not items: return JsonResponse({'success': False, 'error': 'No items in sale'}) with transaction.atomic(): # 1. Revert Stock for item in sale.items.all(): product = item.product product.stock_quantity += item.quantity product.save() # 2. Delete existing items sale.items.all().delete() # 3. Update Sale Details if customer_id: sale.customer_id = customer_id else: sale.customer = None sale.discount = discount sale.notes = notes if invoice_number: sale.invoice_number = invoice_number if due_date: sale.due_date = due_date else: sale.due_date = None # 4. Create New Items and Deduct Stock subtotal = decimal.Decimal(0) for item_data in items: product = Product.objects.get(pk=item_data['id']) quantity = decimal.Decimal(str(item_data['quantity'])) price = decimal.Decimal(str(item_data['price'])) # Deduct stock product.stock_quantity -= quantity product.save() line_total = price * quantity subtotal += line_total SaleItem.objects.create( sale=sale, product=product, quantity=quantity, unit_price=price, line_total=line_total ) sale.subtotal = subtotal sale.total_amount = subtotal - discount # 5. Handle Payments if payment_type == 'credit': sale.status = 'unpaid' sale.paid_amount = 0 sale.balance_due = sale.total_amount sale.payments.all().delete() elif payment_type == 'cash': sale.status = 'paid' sale.paid_amount = sale.total_amount sale.balance_due = 0 sale.payments.all().delete() SalePayment.objects.create( sale=sale, amount=sale.total_amount, payment_method_id=payment_method_id if payment_method_id else None, payment_date=timezone.now().date(), notes='Full Payment (Edit)' ) elif payment_type == 'partial': sale.paid_amount = paid_amount sale.balance_due = sale.total_amount - paid_amount if sale.balance_due <= 0: sale.status = 'paid' sale.balance_due = 0 else: sale.status = 'partial' sale.payments.all().delete() SalePayment.objects.create( sale=sale, amount=paid_amount, payment_method_id=payment_method_id if payment_method_id else None, payment_date=timezone.now().date(), notes='Partial Payment (Edit)' ) sale.save() return JsonResponse({'success': True, 'sale_id': sale.id}) except Sale.DoesNotExist: return JsonResponse({'success': False, 'error': 'Sale not found'}) except Product.DoesNotExist: return JsonResponse({'success': False, 'error': 'Product not found'}) except Exception as e: return JsonResponse({'success': False, 'error': str(e)}) """ with open(file_path, 'r') as f: content = f.read() # Replace stubs content = content.replace("def sale_receipt(request, pk): return redirect('invoices')", sale_receipt_code) content = content.replace("def edit_invoice(request, pk): return redirect('invoices')", edit_invoice_code) content = content.replace("@csrf_exempt\ndef update_sale_api(request, pk): return JsonResponse({'success': False})", update_sale_api_code) # Handle potential whitespace variations if single-line replace fails if "def edit_invoice(request, pk): return redirect('invoices')" in content: # Check if it persisted pass # worked else: # Fallback for manual check if needed (it should work given exact match from read_file) pass with open(file_path, 'w') as f: f.write(content)