coopdevs/lazona_connector

View on GitHub
api/tasks.py

Summary

Maintainability
A
1 hr
Test Coverage
import pprint
from django.utils import timezone
from koiki.client import Client
from koiki.woocommerce.order import LocalPickupOrder
from koiki.resources import KoikiOrder
from koiki.email import FailedDeliveryMail, SuccessDeliveryMail, UpdateDeliveryStatusChangedMail
from sugarcrm.customer import Customer
from lazona_connector.vars import logger, wp_partner_role
from wordpress.user import WPUser
from lazona_connector.celery import app
from django.db.models import Q


@app.task
def create_or_update_delivery(order_data, vendor_id=None):
    from api.models import Shipment, ShipmentStatus, ShipmentMethod
    local_pickup_orders = LocalPickupOrder(order_data)

    for local_vendor_id in local_pickup_orders.by_vendor.keys():
        shipment, created = Shipment.objects.get_or_create(
            order_id=int(local_pickup_orders.order_id),
            vendor_id=int(local_vendor_id)
        )
        shipment.method = ShipmentMethod.LOCAL_PICKUP
        shipment.status = ShipmentStatus.DELIVERED
        shipment.update_at = timezone.now()
        shipment.save()

    koiki_orders = KoikiOrder(order_data).filter_by_vendor(vendor_id)
    deliveries_by_vendor = Client().create_delivery(koiki_orders)

    for delivery in deliveries_by_vendor:
        label_url = ""
        if delivery._is_errored():
            delivery_status = ShipmentStatus.ERROR_FROM_BODY
            FailedDeliveryMail(
                order_id=delivery.get_data_val("order_id"),
                error_returned=delivery.get_data_val("message"),
                req_body=delivery.req_body,
            ).send()
        else:
            delivery_status = ShipmentStatus.LABEL_SENT
            label_url = delivery.print_pdf()

            logger.info("Sending Koiki pdf to vendor with id {}".format(delivery.vendor.id))
            SuccessDeliveryMail(
                pdf_path=label_url,
                recipient=delivery.vendor.email,
                order_id=delivery.get_data_val("order_id"),
            ).send()

        shipment, created = Shipment.objects.get_or_create(
            order_id=int(delivery.get_data_val("order_id")),
            vendor_id=int(delivery.vendor.id),
        )
        shipment.method = ShipmentMethod.KOIKI
        shipment.req_body = pprint.pformat(delivery.req_body)
        shipment.delivery_message = delivery.get_data_val("message")
        shipment.delivery_id = delivery.get_data_val("barcode")
        shipment.label_url = label_url
        shipment.status = delivery_status
        shipment.updated_at = timezone.now()
        shipment.save()


@app.task
def update_delivery_status(delivery_id, email_notify=False):
    from api.models import Shipment, ShipmentStatus

    delivery_status = Client().update_delivery_status(delivery_id)
    if delivery_status and delivery_id:
        shipment = Shipment.objects.get(delivery_id=delivery_id)
        shipment.tracking_updated_at = timezone.now()
        shipment_status = delivery_status.get_data_val("shipment_status")
        old_shipment_status = shipment.status
        old_shipment_delivery_message = shipment.delivery_message
        if delivery_status.is_errored():
            shipment.status = shipment_status
            shipment.delivery_message = delivery_status.get_data_val("response_error_message")
            shipment.tracking_status_created_at = None
        else:
            shipment.tracking_status_created_at = delivery_status.get_data_val("response_date")
            shipment.delivery_notes = delivery_status.get_data_val("response_notes")
            if shipment_status:
                shipment.status = shipment_status
                shipment.delivery_message = delivery_status.get_data_val("response_message")
            else:
                shipment.status = ShipmentStatus.ERROR_FROM_TRACKING
                shipment.delivery_message = "{}. Doesn't match any shipment status".format(
                    delivery_status.get_data_val("response_message")
                )
        shipment.save()
        if email_notify:
            if (
                shipment.status != old_shipment_status
                or shipment.delivery_message != old_shipment_delivery_message
            ):
                UpdateDeliveryStatusChangedMail(shipment).send()
        return True
    return False


@app.task(name="update_delivery_status_periodic")
def update_delivery_status_periodic():
    from api.models import Shipment

    shipments = Shipment.objects.all().exclude(Q(delivery_id="") | Q(status="DELIVERED"))
    if shipments:
        for shipment in shipments:
            logger.info(
                "Updating shipment stratus for delivery id {}".format(shipment.delivery_id)
            )
            update_delivery_status(shipment.delivery_id, email_notify=True)


@app.task
def update_customer_if_is_partner(email):
    if _check_customer_is_partner(email):
        update_user_as_partner.delay(email)


def _check_customer_is_partner(email):
    customer = Customer().fetch(email)
    return customer.check_is_partner()


@app.task
def update_user_as_partner(email):
    wp_user = WPUser().fetch_by_email(email)
    if wp_user.roles and "customer" in wp_user.roles:
        wp_user.update(roles=wp_partner_role)