|
| 1 | +from collections import defaultdict |
| 2 | + |
1 | 3 | from django.db.models import Q |
2 | 4 | from django.utils import numberformat |
3 | 5 | from django.utils.timezone import now |
@@ -452,3 +454,154 @@ def get_data(self): |
452 | 454 | @property |
453 | 455 | def export_name(self): |
454 | 456 | return "billbee-bestellungen-{}".format(now().strftime("%d-%m-%Y")) |
| 457 | + |
| 458 | + |
| 459 | +class CustomerOrderEasyBillExportView(StaffPermissionsMixin, ExportMixin, FilterView): |
| 460 | + filterset_class = CustomerOrderFilter |
| 461 | + model = CustomerOrder |
| 462 | + delimiter = ";" |
| 463 | + |
| 464 | + def get_headers(self): |
| 465 | + headers = [ |
| 466 | + "order_number", |
| 467 | + "item_type", |
| 468 | + "purchase_date", |
| 469 | + "currency", |
| 470 | + "order_shipping_price", |
| 471 | + "payment_type", |
| 472 | + "payment_reference", |
| 473 | + "customer_number", |
| 474 | + "email", |
| 475 | + "phone_number", |
| 476 | + "firstname", |
| 477 | + "lastname", |
| 478 | + "street", |
| 479 | + "zipcode", |
| 480 | + "city", |
| 481 | + "state", |
| 482 | + "country", |
| 483 | + "sku", |
| 484 | + "title", |
| 485 | + "quantity", |
| 486 | + "item_price", |
| 487 | + "vat_percent", |
| 488 | + "tax_type", |
| 489 | + "shipping_date", |
| 490 | + "shipping_type", |
| 491 | + "payment_date", |
| 492 | + "store_id", |
| 493 | + ] |
| 494 | + return headers |
| 495 | + |
| 496 | + def get_data(self): |
| 497 | + customer_orders = ( |
| 498 | + self.object_list.select_related("customer", "customer__user") |
| 499 | + .prefetch_related("positions", "positions__product") |
| 500 | + .order_by("customer", "created") |
| 501 | + ) |
| 502 | + |
| 503 | + # Group orders by customer |
| 504 | + customer_groups = defaultdict(list) |
| 505 | + for order in customer_orders: |
| 506 | + customer_groups[order.customer_id].append(order) |
| 507 | + |
| 508 | + rows = [] |
| 509 | + |
| 510 | + for customer_id, orders in customer_groups.items(): |
| 511 | + # Get the first order for the order number and customer data |
| 512 | + first_order = min(orders, key=lambda x: x.created) |
| 513 | + order_number = first_order.id |
| 514 | + |
| 515 | + # Collect all positions from all orders of this customer |
| 516 | + for order in orders: |
| 517 | + for position in order.positions.all(): |
| 518 | + # Format price |
| 519 | + item_price = "" |
| 520 | + if position.price: |
| 521 | + item_price = numberformat.format( |
| 522 | + position.price.amount, ".", decimal_pos=4, use_l10n=False |
| 523 | + ) |
| 524 | + |
| 525 | + # Determine VAT percentage (default to 7%, adjust as needed) |
| 526 | + vat_percent = "7.0000" |
| 527 | + if hasattr(position.product, "vat_rate"): |
| 528 | + vat_percent = numberformat.format( |
| 529 | + position.product.vat_rate, |
| 530 | + ".", |
| 531 | + decimal_pos=4, |
| 532 | + use_l10n=False, |
| 533 | + ) |
| 534 | + |
| 535 | + # Format dates |
| 536 | + purchase_date = first_order.created.strftime("%Y-%m-%d") |
| 537 | + shipping_date = "" |
| 538 | + payment_date = "" |
| 539 | + |
| 540 | + if hasattr(order, "shipped_date") and order.shipped_date: |
| 541 | + shipping_date = order.shipped_date.strftime("%Y-%m-%d") |
| 542 | + |
| 543 | + if hasattr(order, "paid_date") and order.paid_date: |
| 544 | + payment_date = order.paid_date.strftime("%Y-%m-%d") |
| 545 | + |
| 546 | + row = [ |
| 547 | + str(order_number), |
| 548 | + "item", |
| 549 | + purchase_date, |
| 550 | + "EUR", |
| 551 | + "0.00", # order_shipping_price - adjust if you have shipping costs |
| 552 | + "", # payment_type - add if available |
| 553 | + "", |
| 554 | + ( # payment_reference - add if available |
| 555 | + str(first_order.customer.id) if first_order.customer else "" |
| 556 | + ), |
| 557 | + ( |
| 558 | + first_order.customer.user.email |
| 559 | + if first_order.customer and first_order.customer.user |
| 560 | + else "" |
| 561 | + ), |
| 562 | + ( |
| 563 | + first_order.customer.telephone_number |
| 564 | + if first_order.customer |
| 565 | + else "" |
| 566 | + ), |
| 567 | + ( |
| 568 | + first_order.customer.user.first_name |
| 569 | + if first_order.customer and first_order.customer.user |
| 570 | + else "" |
| 571 | + ), |
| 572 | + ( |
| 573 | + first_order.customer.user.last_name |
| 574 | + if first_order.customer and first_order.customer.user |
| 575 | + else "" |
| 576 | + ), |
| 577 | + ( |
| 578 | + first_order.customer.address_line |
| 579 | + if first_order.customer |
| 580 | + else "" |
| 581 | + ), |
| 582 | + ( |
| 583 | + first_order.customer.postal_code |
| 584 | + if first_order.customer |
| 585 | + else "" |
| 586 | + ), |
| 587 | + first_order.customer.city if first_order.customer else "", |
| 588 | + "", # state |
| 589 | + "DE", |
| 590 | + str(position.product.pk) if position.product else "", |
| 591 | + position.product.name if position.product else "", # country |
| 592 | + str(position.quantity), |
| 593 | + item_price, |
| 594 | + vat_percent, |
| 595 | + "", # tax_type |
| 596 | + shipping_date, |
| 597 | + "", # shipping_type - add if available (e.g., "DHL") |
| 598 | + payment_date, |
| 599 | + "", # store_id - add if you have multiple stores |
| 600 | + ] |
| 601 | + rows.append(row) |
| 602 | + |
| 603 | + return rows |
| 604 | + |
| 605 | + @property |
| 606 | + def export_name(self): |
| 607 | + return "easybill-orders-{}".format(now().strftime("%Y-%m-%d")) |
0 commit comments