38086-vm/patch_views_sales.py
2026-02-08 06:12:20 +00:00

207 lines
7.2 KiB
Python

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)