Эх сурвалжийг харах

Fixed issue on product page that was not checking availability after changing one of the variations

Added weight/shipping calculation on the backend and added shipping calculation if the order amount changes

main.py - added weight as a value for every product

db.py - added extra check on product ids. Included total_weight in order report

cart.py - including total_weiht of the order into cart

schema.py - added weight and total_weight options

.html - changes to files to work with weight

cart.js - Updating total weight value on the checkout page

product.js - making sure that the product check is done also for products without size or style

checkout.js - changing shipping cost on quantity change
slow_tiger 1 жил өмнө
parent
commit
280cebeb31

+ 7 - 0
app/cart.py

@@ -36,6 +36,7 @@ def initialize_cart(session, currency: str) -> dict[int, str] | NoReturn:
                 "order_id": order_id,
                 "currency": currency,
                 "subtotal": 0,
+                "total_weight": 0,
                 "shipping": 0,
                 "total": 0,
                 "item_amount": 0,
@@ -79,6 +80,7 @@ def update_cart_meta(
     """
     session_meta_item_amount = 0
     session_meta_subtotal = 0
+    session_meta_weight = 0
 
     for item in session["items"].values():
         if products is not None:
@@ -106,6 +108,7 @@ def update_cart_meta(
 
                 session_meta_item_amount += item_quantity
                 session_meta_subtotal += item_quantity * item["price"]
+                session_meta_weight += item_quantity * item["options"]["weight"]
 
             # -- update also each item quantity and availability under session.cart.items
             if item["options"]["product_variation_id"]:
@@ -120,9 +123,11 @@ def update_cart_meta(
             # when doing POST /checkout, re-compute meta values
             session_meta_item_amount += item["quantity"]
             session_meta_subtotal += item["quantity"] * item["price"]
+            session_meta_weight += item["quantity"] * item["options"]["weight"]
 
     session["meta"]["item_amount"] = session_meta_item_amount
     session["meta"]["subtotal"] = session_meta_subtotal
+    session["meta"]["total_weight"] = session_meta_weight
 
     # check items amount and eventually reset shipping value
     if len(session["items"]) > 0:
@@ -198,6 +203,7 @@ def update_cart(
                         "product_variation_id": form.options.product_variation_id,
                         "size": form.options.size,
                         "style": form.options.style,
+                        "weight": form.options.weight,
                     },
                     "price": form.price,
                     "quantity": 1,
@@ -219,6 +225,7 @@ def clear_cart(session, currency: str) -> NoReturn:
             "order_id": order_id,
             "currency": currency,
             "subtotal": 0,
+            "total_weight": 0,
             "shipping": 0,
             "total": 0,
             "item_amount": 0,

+ 6 - 0
app/db.py

@@ -57,6 +57,10 @@ def check_product_availability(
                 is_selectable = (variant.amount - quantity) > 0
                 amount = variant.amount
                 break
+    elif len(product.meta.inventory) > 1:
+        for item in product.meta.inventory:
+            if item.amount > 0:
+               is_available, is_selectable, amount =   True, True, 1
     else:
         is_available = product.meta.inventory[0].amount > 0
         is_selectable = (product.meta.inventory[0].amount - quantity) > 0
@@ -306,6 +310,7 @@ def prepare_order_info(
         f"items: \n{items_table}"
         f"currency: '{cm.currency}'\n"
         f"subtotal: '{cm.subtotal}'\n"
+        f"total_weight: '{cm.total_weight}'\n"
         f"shipping: '{cm.shipping}'\n"
         f"total: '{cm.total}'\n"
         f"shipping_info: \n{shipping_info_table}"
@@ -404,6 +409,7 @@ def update_order_info(
                             f"items: \n{items_table}"
                             f"currency: '{order['currency']}'\n"
                             f"subtotal: '{order['subtotal']}'\n"
+                            f"total_weight: '{order['total_weight']}'\n"
                             f"shipping: '{order['shipping']}'\n"
                             f"total: '{order['total']}'\n"
                             f"shipping_info: \n{shipping_info_table}"

+ 3 - 2
app/main.py

@@ -452,10 +452,11 @@ async def checkout_update(
         product_id=product_id,
         options={"size": size,
                  "style": style,
-                 "product_variation_id": product_variation_id
+                 "product_variation_id": product_variation_id,
+                 "weight": selected_product.meta.weight,
                  },
         price=price,
-    )    
+    )
 
     quantity_requested_by_user = calculate_quantity_requested_by_user(
         session_data["cart"]["items"], product_id, quantity

+ 3 - 0
app/schema.py

@@ -37,6 +37,7 @@ class CartSessionMeta(BaseModel):
     order_id: str
     currency: str
     subtotal: int = 0
+    total_weight: int = 0
     shipping: float = 0.0
     total: float = 0.0
     item_amount: int = 0
@@ -46,6 +47,7 @@ class CartSessionItemOptions(BaseModel):
     product_variation_id: str | None = None
     size: Literal["s", "m", "l", "xl", "xxl"] | None
     style: str | None
+    weight: int | None
 
 
 class CartSessionItem(BaseModel):
@@ -288,6 +290,7 @@ class OrdersBlock(BaseModel):
     items: list[OrdersBlockItem]
     currency: str
     subtotal: int
+    total_weight: int
     shipping: float
     total: float
     shipping_info: OrdersBlockShippingInfo

+ 1 - 3
app/templates/checkout.html

@@ -20,9 +20,7 @@
   {% if data.show_checkout %}
   <form class="checkout-shipping-info w100 pt4-25" method="POST">
     <input type="hidden" id="order_id" name="order_id" value="{{ cart.meta.order_id }}">
-    {% for item in data.checkout_items %}
-    <input type="hidden" id="weight" name="weight" value="{{ item.weight }}">
-    {% endfor %}
+    <input type="hidden" id="weight" name="weight" value="{{ cart.meta.total_weight }}">
     <section class="w100 bdb-dark-red pr0-85 pb4-25 pl0-85">
       {% include "partials/form-subtotal.html" %}
     </section>

+ 5 - 1
app/templates/partials/checkout-item-form.html

@@ -8,13 +8,17 @@
   {% endif %}
   <input type="hidden" id="page" name="page" value="checkout">
   <input type="hidden" id="operation" name="operation" value="{{ operation }}">
+  {% if item.options.product_variation_id %}
+  <input type="hidden" id="product_id" name="product_id" value="{{ item.options.product_variation_id }}">
+  {% else %}
   <input type="hidden" id="product_id" name="product_id" value="{{ item.product_id }}">
+  {% endif %}
   <input type="hidden" id="product_path" name="product_path" value="{{ item.path }}">
   <input type="hidden" id="price" name="price" value="{{ item.price }}">
   {% if item.options.style %}
   <input type="hidden" id="style" name="style" value="{{ item.options.style }}">
   {% endif %}
-  {% if item.options.style %}
+  {% if item.options.size %}
   <input type="hidden" id="size" name="size" value="{{ item.options.size }}">
   {% endif %}
   {% if operation == 'delete' %}

+ 3 - 0
static/js/cart.js

@@ -98,6 +98,9 @@ function updateBreakdown(cart_breakdown) {
     subtotal_total.textContent = `${cart_breakdown.total.toFixed(1)}`;
   };
 
+  let weight = document.getElementById("weight");
+  weight.value = `${cart_breakdown.total_weight}`;
+
 }
 
 function removeCheckoutTable() {

+ 8 - 0
static/js/checkout.js

@@ -32,6 +32,14 @@ async function processForm(form) {
       const btnSubmit = document.querySelector('.btn-submit');
 
       displayProductSelectable(btnSubmit, isProductSelectable, isProductAvailable);
+    }
+
+    // update shipping cost on amount change
+    const selectCountry = document.querySelector('select#country');
+    const shipping_data = prepareShippingCost(selectCountry);
+    if (shipping_data !== undefined) {
+      const cart_breakdown_shipping = await updateShippingCost(shipping_data.country, shipping_data.weight, shipping_data.csrftoken);
+	  updateBreakdown(cart_breakdown_shipping);
     };
 
   });

+ 2 - 2
static/js/product.js

@@ -45,7 +45,7 @@ async function checkProductAvailability(product_path, searchParams){
 async function changeProductURLOnInputRadio(form) {
   // add on-change listener to all .input-listen input fields
   // and update URL accordingly
-  
+
   const inputs = Array.from(form.querySelectorAll('.input-listen'));
   await Promise.all(inputs.map(async(input) => {
     input.addEventListener('change', async(e) => {
@@ -66,7 +66,7 @@ async function changeProductURLOnInputRadio(form) {
 	let size = searchParams.get('size');
 	let style = searchParams.get('style');
 
-	if (size && style) {
+	if (size || style) {
 	  const data = await checkProductAvailability(product_path, searchParams);
 
 	  // -- update product availability