38086-vm/core/patch_views_vat.py
Flatlogic Bot 9dfa03d69c adding vat
2026-02-05 13:09:11 +00:00

161 lines
6.7 KiB
Python

@csrf_exempt
def create_sale_api(request):
if request.method == 'POST':
try:
data = json.loads(request.body)
customer_id = data.get('customer_id')
invoice_number = data.get('invoice_number', '')
items = data.get('items', [])
# Retrieve amounts
subtotal = data.get('subtotal', 0)
vat_amount = data.get('vat_amount', 0)
total_amount = data.get('total_amount', 0)
paid_amount = data.get('paid_amount', 0)
discount = data.get('discount', 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', '')
# Loyalty data
points_to_redeem = data.get('loyalty_points_redeemed', 0)
customer = None
if customer_id:
customer = Customer.objects.get(id=customer_id)
if not customer and payment_type != 'cash':
return JsonResponse({'success': False, 'error': _('Credit or Partial payments are not allowed for Guest customers.')}, status=400)
settings = SystemSetting.objects.first()
if not settings:
settings = SystemSetting.objects.create()
loyalty_discount = 0
if settings.loyalty_enabled and customer and points_to_redeem > 0:
if customer.loyalty_points >= points_to_redeem:
loyalty_discount = float(points_to_redeem) * float(settings.currency_per_point)
sale = Sale.objects.create(
customer=customer,
invoice_number=invoice_number,
subtotal=subtotal,
vat_amount=vat_amount,
total_amount=total_amount,
paid_amount=paid_amount,
balance_due=float(total_amount) - float(paid_amount),
discount=discount,
loyalty_points_redeemed=points_to_redeem,
loyalty_discount_amount=loyalty_discount,
payment_type=payment_type,
due_date=due_date if due_date else None,
notes=notes,
created_by=request.user
)
# Set status based on payments
if float(paid_amount) >= float(total_amount):
sale.status = 'paid'
elif float(paid_amount) > 0:
sale.status = 'partial'
else:
sale.status = 'unpaid'
sale.save()
# Record initial payment if any
if float(paid_amount) > 0:
pm = None
if payment_method_id:
pm = PaymentMethod.objects.filter(id=payment_method_id).first()
SalePayment.objects.create(
sale=sale,
amount=paid_amount,
payment_method=pm,
payment_method_name=pm.name_en if pm else payment_type.capitalize(),
notes="Initial payment",
created_by=request.user
)
for item in items:
product = Product.objects.get(id=item['id'])
SaleItem.objects.create(
sale=sale,
product=product,
quantity=item['quantity'],
unit_price=item['price'],
line_total=item['line_total']
)
product.stock_quantity -= int(item['quantity'])
product.save()
# Handle Loyalty Points
if settings.loyalty_enabled and customer:
# Earn Points
points_earned = float(total_amount) * float(settings.points_per_currency)
if customer.loyalty_tier:
points_earned *= float(customer.loyalty_tier.point_multiplier)
if points_earned > 0:
customer.loyalty_points += decimal.Decimal(str(points_earned))
LoyaltyTransaction.objects.create(
customer=customer,
sale=sale,
transaction_type='earned',
points=points_earned,
notes=f"Points earned from Sale #{sale.id}"
)
# Redeem Points
if points_to_redeem > 0:
customer.loyalty_points -= decimal.Decimal(str(points_to_redeem))
LoyaltyTransaction.objects.create(
customer=customer,
sale=sale,
transaction_type='redeemed',
points=-points_to_redeem,
notes=f"Points redeemed for Sale #{sale.id}"
)
customer.update_tier()
customer.save()
return JsonResponse({
'success': True,
'sale_id': sale.id,
'business': {
'name': settings.business_name,
'address': settings.address,
'phone': settings.phone,
'email': settings.email,
'currency': settings.currency_symbol,
'vat_number': settings.vat_number,
'registration_number': settings.registration_number,
'logo_url': settings.logo.url if settings.logo else None
},
'sale': {
'id': sale.id,
'invoice_number': sale.invoice_number,
'created_at': sale.created_at.strftime("%Y-%m-%d %H:%M"),
'subtotal': float(sale.subtotal),
'vat_amount': float(sale.vat_amount),
'total': float(sale.total_amount),
'discount': float(sale.discount),
'paid': float(sale.paid_amount),
'balance': float(sale.balance_due),
'customer_name': sale.customer.name if sale.customer else 'Guest',
'items': [
{
'name_en': si.product.name_en,
'name_ar': si.product.name_ar,
'qty': si.quantity,
'price': float(si.unit_price),
'total': float(si.line_total)
} for si in sale.items.all()
]
}
})
except Exception as e:
return JsonResponse({'success': False, 'error': str(e)}, status=400)