Beispiel #1
0
def get_internal_shipment(params):
    shipment_id = params.get('id')
    reference = params.get('reference')

    if shipment_id:
        url = f'{FULFIL_API_URL}/model/stock.shipment.internal/{shipment_id}'

        response = requests.get(url, headers=headers)

        if response.status_code == 200:
            return response.json()

        send_email("Fulfil: failed to get internal shipment",
                   f"Failed to get IS with {shipment_id} ID")

    elif reference:
        url = f'{FULFIL_API_URL}/model/stock.shipment.internal?reference={reference}'

        response = requests.get(url, headers=headers)

        if response.status_code == 200:
            return response.json()[0]

        send_email("Fulfil: failed to get internal shipment",
                   f"Failed to get {reference} IS")

    return None
Beispiel #2
0
def check_request_signature(request):
    try:
        webhook_secret = 'f5d0c396ba09b4c2'.encode('utf-8')
        headers = request.headers
        signature = headers.get("X-Loop-Signature", '')

        body = request.raw_body
        hashed = hmac.new(webhook_secret, body, hashlib.sha256)
        decoded = base64.b64encode(hashed.digest()).decode()
        if decoded == signature:
            return True
        else:
            send_email(subject="loopreturns: signature, error",
                       content=f"{body}\n{signature}",
                       dev_recipients=True)
    except Exception as e:
        print("check_request_signature error")
        traceback.print_exc()
        try:
            print(headers)
            print(body)
            print(signature)
            print(decoded)
        except:
            pass
Beispiel #3
0
def notify_end_up_boxes(few_boxes):
    info = str(listDictsToHTMLTable(few_boxes))
    send_email(
        f"Boxes are ending up",
        f"{date.today().strftime('%Y-%m-%d')}<br>" + info,
        dev_recipients=True,
        email=['*****@*****.**'],
    )
 def check_products(self, products):
     for key, value in products.items():
         if self.ruby_quantities[key] < value:
             send_email(
                 "!!!IMPORTANT: Internal shipments (product check result)",
                 f"problem with {key} created internal shipment "
                 f"with values ({value}) more then available "
                 f"on rubyhas {self.ruby_quantities[key]}",
                 dev_recipients=True)
             products[key] = self.ruby_quantities[key]
Beispiel #5
0
def capture_error(error, data=None, email=None, **tags):
    tags.setdefault('environment', EVIRONMENT)
    with configure_scope() as scope:
        for tag, value in tags.items():
            scope.set_tag(tag, value)
        if data:
            sentry_sdk.set_context('DATA', data)
        capture_exception(error, scope=scope)
    if email:
        send_email(error, str(data), email=email)
Beispiel #6
0
def find_late_orders():
    from app import BASE_DIR
    days_delay = 2
    emails = get_n_days_old_orders(days_delay, late=True)
    template = Template(
        open(f'{BASE_DIR}/chalicelib/template/late_order.html').read())

    if emails:
        late_orders_report = []
        for sale in emails:
            shipment, email_type, moves, planned_date = get_oldest_shipment(
                sale)
            if planned_date in dates_with_passed_some_work_days(days_delay) \
                    and (shipment['shipping_instructions'] == None or
                    'Planned date delayed' not in shipment['shipping_instructions']):
                report = {
                    'Shopify Order': sale['reference'],
                    'Customer Name': sale['party.name'],
                    'Customer Email': sale['party.email'],
                    'Planned Date Changed': 'No',
                }

                data = {
                    'YEAR': str(date.today().year),
                    'FINISH_DATE': planned_date,
                    # 'TRACK_LINK': get_link(sale['reference']),
                    'items': moves,
                    'TEXT': LATE_ORDER_TEXT[email_type]
                }
                result = template.render(**data)

                send_email(
                    f"A small hiccup on our end",
                    result,
                    email=sale['party.email'],
                    # email=['*****@*****.**'],
                    # dev_recipients=True,
                    from_email='*****@*****.**',
                )
                # break
                if email_type in ['mto', 'vermeil']:
                    update_planned_date(shipment, email_type)
                    report['Planned Date Changed'] = 'Yes'
                late_orders_report.append(report)
        if late_orders_report:
            send_email(
                f"Fulfil: found {len(late_orders_report)} late orders",
                str(listDictsToHTMLTable(late_orders_report)),
                email=['*****@*****.**', '*****@*****.**'],
                # email=['*****@*****.**'],
                dev_recipients=True)
Beispiel #7
0
def process_boxes():
    shipments = collect_info()
    get_boxes()
    col_boxes = collect_boxes(shipments)
    updated_sku_by_warehouse = sku_for_update(col_boxes)
    try:
        sku_for_report = []
        count = 'Nothing changed'
        for storage, updated_sku in updated_sku_by_warehouse.items():
            sku_for_report.extend(updated_sku)

            count = new_inventory(updated_sku, storage)
            complete_inventory(count)
            confirm_inventory(count)

        add_box_comment(shipments)

        info = str(listDictsToHTMLTable(sku_for_report))
        info += f'<br> processed CS {[item["rec_name"] for item in shipments]}'
        send_email(
            f"Fullfill: Sync boxes",
            f"{date.today().strftime('%Y-%m-%d')}, done. Inventory id {count}<br>"
            + info,
            dev_recipients=True,
            email=['*****@*****.**'],
        )
    except Exception as e:
        info = str(listDictsToHTMLTable(sku_for_report))
        info += f'processed CS {[item["rec_name"] for item in shipments]}'
        send_email(
            f"Fullfill: Sync boxes Fail",
            f"{date.today().strftime('%Y-%m-%d')}, fail <br>" + info,
            dev_recipients=True,
            email=['*****@*****.**'],
        )
        print(traceback.format_exc())
 def send_email(self):
     if self.message:
         send_email(f"Fulfil Report: Internal shipments automatic",
                    self.message,
                    email=['*****@*****.**'],
                    dev_recipients=True)
Beispiel #9
0
def email_report():
    db_ref = get_db()
    records = db_ref.fetch_report_data()
    email.send_email(records)
Beispiel #10
0
    },
    'reminder': {
        'subject': 'About that warranty claim',
        'data': {
            'PREH': 'Reminder!',
            'HEADER': 'Request Approved!',
            'LINK_TEXT': 'NEXT STEPS',
            'TEXT': '''
            We’ve approved your repair request and ready to receive it. 
            Use the link below and fill the tracking number to track your parcel.
        ''',
        }
    },
}

def send_repearment_email(email, case, NOTE=None, DT=None):
    from app import BASE_DIR
    info = REPEARMENT_CASE[case]
    if DT:
        LINK = f"https://warrantyclaims.auratenewyork.com/info?DT={DT}"
        info['data']['LINK'] = LINK
    template = Template(
        open(f'{BASE_DIR}/chalicelib/template/notification.html').read())

    content = template.render(**info['data'], **{"NOTE": NOTE},)

    send_email(info['subject'],
               content,
               email=email,
               dev_recipients=False,
               from_email='*****@*****.**')
Beispiel #11
0
def return_created(body):
    errors = []
    Model = client.model('sale.sale')
    sale = Model.search_read_all(
        domain=[["AND", ["reference", "=", body['order_name']]]],
        order=None,
        fields=['id', 'lines'],
        # batch_size=5,
    )
    sale = list(sale)
    if not sale:
        errors.append(
            f"Can't create return, didn't find any sale with reference {body['order_name']}"
        )
        return errors

    sale = sale[0]
    Model = client.model('sale.line')
    f_lines = Model.search_read_all(
        domain=[["AND", ["id", "in", sale['lines']]]],
        order=None,
        fields=['product', 'product.code', 'quantity'],
    )
    f_lines = list(f_lines)
    if not f_lines:
        errors.append(
            f"Can't create return, didn't find any sale lines with reference {body['order_name']}"
        )
        return errors

    order_id = sale['id']
    url = f'{get_fulfil_model_url("sale.sale")}/{order_id}/return_order'

    lines = []
    for body_l in body['line_items']:
        ll = filter(lambda x: x['product.code'] == body_l['sku'], f_lines)
        if not ll:
            errors.append(f"Line not found {body_l}\n")
            continue

        line = ll.__next__()
        line_id = line['id']

        lines.append({
            # Optional fields on line
            # ==================
            # "return_quantity": body_l[''],
            # defaults to the order line returnable quantity
            # "unit_price": "320.45",
            # defaults to the original order line unit price. Change this amount if the refund is not the full amount of the original order line.

            # If the return was created on an external returns platform,
            # the ID of the line
            # "order_line_id": line_id,
            # "channel_identifier": body_l['line_item_id'],
            # "return_reason": body_l["return_reason"],  # Created if not exists
            # "note": "tracking_number " + body['tracking_number'],
            "note": body_l['return_comment'],
            "return_quantity": 1,
            "order_line_id": line_id,
            "channel_identifier": body_l['line_item_id'],
            "return_reason": body_l["return_reason"],  # Created if not exists
        })

    if not lines:
        errors.append("Can't create return, didn't find any line")
        return errors

    if body['exchanges']:
        Model = client.model('product.product')

    # # exchanges created through shopify
    # for i, item in enumerate(body['exchanges']):
    #     if len(lines) > i:
    #         product = Model.search_read_all(
    #             domain=[["AND", ["code", "=", item['sku']]]],
    #             order=None,
    #             fields=['id'],
    #         )
    #         product_id = product.__next__()['id']
    #         lines[i]['exchange_quantity'] = 1
    #         lines[i]['exchange_product'] = product_id
    #         lines[i]['exchange_unit_price'] = item['total']
    #         # # Exchange fields
    #         # # ==================
    #         # # +ve quantity of replacement item to ship to customer
    #         # "exchange_quantity": 1,
    #         # # ID of the product being sent.
    #         # # If replacement item is not specified, the same outbound item will be shipped.
    #         # "exchange_product": 1234,
    #         # # If the unit price is not specified, the unit price of the exchanged item is used.
    #         # "exchange_unit_price": "320.45",  # Unit price for outbound item
    #     else:
    #         errors.append(f"failed to add exchange for {item}\n "
    #                       f"there is more exchanges than returns")
    #         break
    payload = [{
        "channel_identifier": body[
            'id'],  # Unique identifier for the return in the channel. This will be used as idempotency key to avoid duplication.
        "reference":
        'return-' + body["order_name"],  # Return order reference, RMA
        "lines": lines,
        "warehouse": 140,
    }]

    response = requests.put(url, json=payload, headers=headers)

    if response.status_code != 200:
        content = f'''
        error response from fullfill: {response.status_code}<br/>
        text: {response.text}<br/>
        url {url}<br/>
        payload: <br/>
        {json.dumps(payload)}
        '''
        send_email("Loop webhook error!!!!", content, dev_recipients=True)

    return response.text, errors