コード例 #1
0
ファイル: __init__.py プロジェクト: prakashpp/tap-fulfil
def sync_records(config, state, stream):
    write_schema(
        stream.tap_stream_id,
        stream.schema.to_dict(),
        stream.key_properties,
    )

    client = Client(config['subdomain'], config['api_key'])
    model_name = STREAM_MODEL_MAP[stream.tap_stream_id]
    model = client.model(model_name)
    domain = get_sync_domain(state, stream, model_name)
    sort_order = [
        ('write_date', 'asc'),
        ('create_date', 'asc'),
        ('id', 'asc'),
    ]

    # Get all fields defined in schema now
    fields = list(stream.schema.properties.keys())

    # Add create and write date to keep track of state
    fields.extend(['id', 'create_date', 'write_date'])
    for record in model.search_read_all(domain, sort_order, fields):
        transform(record)
        write_record(stream.tap_stream_id, record, time_extracted=utils.now())
        state = write_bookmark(state, stream.tap_stream_id, 'last_updated_at',
                               record['write_date'] or record['create_date'])
        state = write_bookmark(state, stream.tap_stream_id, 'last_record_id',
                               record['id'])
        write_state(state)
コード例 #2
0
 def init_app(self, app):
     '''Initalizes the application with the extension.
     :param app: The Flask application object.
     '''
     self.client = Client(
         app.config['FULFIL_SUBDOMAIN'],
         app.config['FULFIL_API_KEY'],
     )
     app.jinja_env.filters['client_url'] = client_url
コード例 #3
0
 def fulfil_client(self):
     key = 'fulfil:user:%s:context' % self.token
     context = redis_store.get(key)
     if context:
         client = Client(self.subdomain,
                         auth=BearerAuth(self.token),
                         context=json.loads(context))
     else:
         client = Client(self.subdomain, auth=BearerAuth(self.token))
         redis_store.set(key, json.dumps(client.context), 300)  # TTL 5min
     return client
コード例 #4
0
ファイル: __init__.py プロジェクト: sayatul/flask-fulfil
 def init_app(self, app):
     '''Initalizes the application with the extension.
     :param app: The Flask application object.
     '''
     offline_access_token = app.config.get('FULFIL_OFFLINE_ACCESS_TOKEN')
     if offline_access_token:
         self.client = Client(app.config['FULFIL_SUBDOMAIN'],
                              auth=BearerAuth(offline_access_token))
     else:
         self.client = Client(
             app.config['FULFIL_SUBDOMAIN'],
             app.config['FULFIL_API_KEY'],
         )
     app.jinja_env.filters['client_url'] = client_url
コード例 #5
0
ファイル: __init__.py プロジェクト: fulfilio/flask-fulfil
 def init_app(self, app):
     '''Initalizes the application with the extension.
     :param app: The Flask application object.
     '''
     offline_access_token = app.config.get('FULFIL_OFFLINE_ACCESS_TOKEN')
     if offline_access_token:
         self.client = Client(
             app.config['FULFIL_SUBDOMAIN'],
             auth=BearerAuth(offline_access_token)
         )
     else:
         self.client = Client(
             app.config['FULFIL_SUBDOMAIN'],
             app.config['FULFIL_API_KEY'],
         )
     app.jinja_env.filters['client_url'] = client_url
コード例 #6
0
class Fulfil(object):
    """

    To get started you will wrap your application's app object something like
    this::

        app = Flask(__name__)
        fulfil = Fulfil(app)

    Configuration::

        FULFIL_SUBDOMAIN: the subdomain of your Fulfil account.
        FULFIL_API_KEY: The API_KEY to access Fulfil services.

    :param app: The Flask application object. Defaults to None.
    """
    client = None

    def __init__(self, app=None):
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        '''Initalizes the application with the extension.
        :param app: The Flask application object.
        '''
        offline_access_token = app.config.get('FULFIL_OFFLINE_ACCESS_TOKEN')
        if offline_access_token:
            self.client = Client(
                app.config['FULFIL_SUBDOMAIN'],
                auth=BearerAuth(offline_access_token),
                retry_on_rate_limit=True,
            )
        else:
            self.client = Client(
                app.config['FULFIL_SUBDOMAIN'],
                app.config['FULFIL_API_KEY'],
                retry_on_rate_limit=True,
            )
        app.jinja_env.filters['client_url'] = client_url

    def model(self, name):
        return self.client.model(name)

    def record(self, model_name, record_id):
        return self.client.record(model_name, record_id)
コード例 #7
0
class TestFulfilClient(unittest.TestCase):
    def setUp(self):
        try:
            self.client = Client('fulfil_demo', os.environ['FULFIL_API_KEY'])
        except KeyError:
            self.fail('No FULFIL_API_KEY in environment')

    def tearDown(self):
        pass

    def test_000_connection(self):
        Model = self.client.model('ir.model')
        self.assertTrue(len(Model.search([])) > 0)

    def test_010_connection(self):
        Model = self.client.model('ir.model')
        with self.assertRaises(ServerError):
            Model.search([], context=1)
コード例 #8
0
 def init_app(self, app):
     '''Initalizes the application with the extension.
     :param app: The Flask application object.
     '''
     self.client = Client(
         app.config['FULFIL_SUBDOMAIN'],
         app.config['FULFIL_API_KEY'],
     )
     app.jinja_env.filters['client_url'] = client_url
コード例 #9
0
ファイル: __init__.py プロジェクト: fulfilio/flask-fulfil
class Fulfil(object):
    """

    To get started you will wrap your application's app object something like
    this::

        app = Flask(__name__)
        fulfil = Fulfil(app)

    Configuration::

        FULFIL_SUBDOMAIN: the subdomain of your Fulfil account.
        FULFIL_API_KEY: The API_KEY to access Fulfil services.

    :param app: The Flask application object. Defaults to None.
    """
    client = None

    def __init__(self, app=None):
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        '''Initalizes the application with the extension.
        :param app: The Flask application object.
        '''
        offline_access_token = app.config.get('FULFIL_OFFLINE_ACCESS_TOKEN')
        if offline_access_token:
            self.client = Client(
                app.config['FULFIL_SUBDOMAIN'],
                auth=BearerAuth(offline_access_token)
            )
        else:
            self.client = Client(
                app.config['FULFIL_SUBDOMAIN'],
                app.config['FULFIL_API_KEY'],
            )
        app.jinja_env.filters['client_url'] = client_url

    def model(self, name):
        return self.client.model(name)

    def record(self, model_name, record_id):
        return self.client.record(model_name, record_id)
コード例 #10
0
ファイル: extensions.py プロジェクト: iamneha/kitchensink
def get_fulfil():
    subdomain = Config.FULFIL_SUBDOMAIN
    offline_access_token = Config.FULFIL_OFFLINE_ACCESS_TOKEN
    try:
        return Client(
            subdomain,
            auth=BearerAuth(offline_access_token)
        )
    except ClientError, e:
        if e.code == 401:
            # unauthorized
            flask.abort(flask.redirect(flask.url_for('user.logout')))
        raise
コード例 #11
0
class TestFulfilClient(unittest.TestCase):

    def setUp(self):
        try:
            self.client = Client('fulfil_demo', os.environ['FULFIL_API_KEY'])
        except KeyError:
            self.fail('No FULFIL_API_KEY in environment')

    def tearDown(self):
        pass

    def test_000_connection(self):
        Model = self.client.model('ir.model')
        self.assertTrue(len(Model.search([])) > 0)
コード例 #12
0
def get_fulfil():
    if 'fulfil' not in flask.session:
        return

    session_data = flask.session['fulfil']
    try:
        return Client(
            flask.session['subdomain'],
            auth=BearerAuth(
                session_data['oauth_token']['access_token']
            )
        )
    except ClientError as e:
        if e.code == 401:
            # unauthorized
            # TODO: Use refresh token if possible
            flask.abort(flask.redirect(flask.url_for('user.logout')))
        raise
コード例 #13
0
def get_fulfil():
    subdomain = Config.FULFIL_SUBDOMAIN

    access_token = Config.FULFIL_OFFLINE_ACCESS_TOKEN

    if 'FULFIL_ACCESS_TOKEN' in flask.session:
        # Use current login token
        access_token = flask.session['FULFIL_ACCESS_TOKEN']

    if access_token is None:
        flask.abort(403)

    try:
        return Client(
            subdomain,
            auth=BearerAuth(access_token)
        )
    except ClientError, e:
        if e.code == 401:
            # unauthorized
            flask.abort(flask.redirect(flask.url_for('user.logout')))
        raise
コード例 #14
0
def client():
    return Client('fulfil_demo', os.environ['FULFIL_API_KEY'])
コード例 #15
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from fulfil_client import Client
client = Client('<subdomain>', '<api_key>')


# =============
# Creating Sale
# =============

# Sale requires customer(contact) and address id.
Contact = client.model('party.party')
Sale = client.model('sale.sale')

# Get the contact first
contacts = Contact.find([('name', 'ilike', '%Jon%')])
contact, = Contact.get(contacts[0]['id'])

sale, = Sale.create([{
    'party': contact['id'],
    'shipment_address': contact['addresses'][0],
    'invoice_address': contact['addresses'][0],
}])

# ===========================
# Adding items(line) to Sale
# ===========================

Product = client.model('product.product')
Line = client.model('sale.line')
コード例 #16
0
import json
import os
from datetime import date, timedelta, datetime

import requests
from fulfil_client import Client
from jinja2 import Template

from chalicelib import FULFIL_API_URL
from chalicelib.easypsot_tracking import get_n_days_old_orders
from .common import dates_with_passed_some_work_days, listDictsToHTMLTable
from chalicelib.email import send_email

client = Client(os.environ.get('FULFIL_API_DOMAIN', 'aurate-sandbox'),
                os.environ.get('FULFIL_API_KEY', ''))

LATE_ORDER_TEXT = {
    'late':
    """
<p>First off, thank you so much for getting your gold with us. Your support means the world.</p>
<p>Your order has unfortunately missed its estimated "ship by" date. Our deepest apologies here  -- we know you’ve got places to be, people to see, and new looks to rock (even if it’s just virtually). Your gold is currently in good hands and should be ready shortly, but for an exact ETA our team at [email protected] is here for you.</p>
<p>Since we always strive for 100% perfection and don’t like being late, ever, please use the code IOU10 for 10% off your next order.</p>
<p>Thanks so much for your patience. We promise we’re doing everything we can to make sure your gold is worth the wait.</p>
<p>Warmest</p>
<p>X</p>
<p>The A-Team</p>
    """,
    'mto':
    """
<p>First off, thank you so much for getting your gold with us. Your support means the world.</p>
<p>Your order has unfortunately missed its estimated "ship by" date. Our deepest apologies here  -- we know you’ve got places to be, people to see, and new looks to rock (even if it’s just virtually). Your gold just needs a little extra attention; we expect to ship it out within the next 2-10 business days. If this causes any questions or concerns, please reach out to us at [email protected] and we will help in any way we can.</p>
コード例 #17
0
"""
Translate fulfil requests to curl.

Need to have the following installed

pip install curlify blinker
"""
import os
import curlify
from fulfil_client import Client
from fulfil_client.signals import response_received, signals_available

fulfil = Client(os.environ['FULFIL_SUBDOMAIN'], os.environ['FULFIL_API_KEY'])

print("Signal Available?:", signals_available)

Product = fulfil.model('product.product')

products = Product.find([])


@response_received.connect
def curlify_response(response):
    print('=' * 80)
    print(curlify.to_curl(response.request))
    print('=' * 80)
    print(response.content)
    print('=' * 80)


print Product.get_next_available_date(products[0]['id'], 1, 4, True)
コード例 #18
0
ファイル: contact.py プロジェクト: uzayr/fulfil-python-api
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from fulfil_client import Client
client = Client('<subdomain>', '<api_key>')


# =================
# Creating Contacts
# =================

Contact = client.model('party.party')
contact, = Contact.create([{'name': 'Jon Doe'}])

# You can create multiple contacts too ;-)
contacts = Contact.create([
    {
        'name': 'Jon Doe'
    }, {
        'name': 'Matt Bower'
    }, {
        'name': 'Joe Blow'
    }
])

# ================
# Creating Address
# ================

# You need a contact id to create a address
Address = client.model('party.address')
コード例 #19
0
from fulfil_client import Client

# Initializing Api
client = Client('indiraactive', '4b7b1a442e8a44e69e3c5d8ad8a64386')

# Initializing Fulfil's Product model
Product = client.model('product.product')

# Getting all the Product ids
products = Product.search([()])

# Making a write call on list of products to update "hs_code"
# Processing purchase orders in batches of 100
for i in range(0, len(products), 100):
    Product.write(products[i:i + 100], {'hs_code': '3926.20'})
コード例 #20
0
def test_403():
    "Connect with invalid creds and get ClientError"
    with pytest.raises(ClientError):
        Client('demo', 'xxxx')
コード例 #21
0
 def setUp(self):
     try:
         self.client = Client('fulfil_demo', os.environ['FULFIL_API_KEY'])
     except KeyError:
         self.fail('No FULFIL_API_KEY in environment')
コード例 #22
0
ファイル: conftest.py プロジェクト: sayatul/fulfil-python-api
def oauth_client():
    return Client('demo', auth=BearerAuth(os.environ['FULFIL_OAUTH_TOKEN']))
コード例 #23
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
This is a complete example where you have to push an order to Fulfil.IO. The
steps are:

    1. Fetch inventory for the products that have been sold
    2. Create new customer, address
    3. Process the order.
"""
from datetime import date
from decimal import Decimal

from fulfil_client import Client
client = Client('<subdomain>', '<api_key>')


def get_warehouses():
    """
    Return the warehouses in the system
    """
    StockLocation = client.model('stock.location')
    return StockLocation.find(
        [('type', '=', 'warehouse')],  # filter just warehouses
        fields=['code', 'name']  # Get the code and name fields
    )


def get_product_inventory(product_id, warehouse_ids):
    """
    Return the product inventory in each location. The returned response
コード例 #24
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from decimal import Decimal

from fulfil_client import Client
client = Client('<subdomain>', '<api_key>')


# ==========================
# Creating Product Template
# ==========================

Template = client.model('product.template')

iphone, = Template.create([{
    'name': 'iPhone',
    'account_category': True,
}])

# =================
# Creating Products
# =================

Product = client.model('product.product')

iphone6, = Product.create([{
    'template': iphone['id'],
    'variant_name': 'iPhone 6',
    'code': 'IPHONE-6',
    'list_price': Decimal('699'),
    'cost_price': Decimal('599'),
コード例 #25
0
from chalicelib.decorators import try_except

subdomain = os.environ.get('FULFIL_API_DOMAIN', 'aurate-sandbox')


def get_fulfil_model_url(param):
    FULFIL_API_URL = f'https://{subdomain}.fulfil.io/api/v2'
    return f'{FULFIL_API_URL}/model/{param}'


headers = {
    'X-API-KEY': os.environ.get('FULFIL_API_KEY'),
    'Content-Type': 'application/json'
}

client = Client(subdomain, os.environ.get('FULFIL_API_KEY', ''))

a = {
    "topic":
    "return",
    "trigger":
    "return.created",
    "id":
    "6042537",
    "state":
    "open",
    "created_at":
    "2020-10-29T16:07:31+00:00",
    "total":
    "0.13",
    "order_id":
コード例 #26
0
def test_raises_client_error():
    with pytest.raises(ClientError):
        Client('demo', 'wrong-api-key')
コード例 #27
0
def create_fullfill_order(item):
    item['service'] = 'ring reshaping'

    subdomain = 'aurate'
    # subdomain = 'aurate-sandbox'
    token = 'ee41ebf87f4a4fd29696f8b5db6b8cfc'
    # token = '43cf9ddb7acc4ac69586b8f1081d65ab'
    client = Client(subdomain, token)
    headers = {'X-API-KEY': token, 'Content-Type': 'application/json'}

    def get_fulfil_model_url(param):
        FULFIL_API_URL = f'https://{subdomain}.fulfil.io/api/v2'
        return f'{FULFIL_API_URL}/model/{param}'

    errors = []
    Model = client.model('sale.sale')
    sale = Model.search_read_all(
        domain=[["AND", ["reference", "=", item['order_name']]]],
        order=None,
        fields=['id', 'lines'],
        # batch_size=5,
    )
    DT = str(int(item['DT']))
    sale = sale.__next__()
    order_id = sale['id']

    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)
    # from .loopreturns import get_fulfil_model_url
    url = f'{get_fulfil_model_url("sale.sale")}/{order_id}/return_order'

    lines = []
    if True:
        ll = filter(lambda x: x['product.code'] == item['sku'], f_lines)
        line = ll.__next__()
        line_id = line['id']

        lines.append({
            "order_line_id": line_id,
            # 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
            "channel_identifier": DT,
            "note": "tracking_number " + item['tracking_number'],
            "return_reason": item['service'],  # Created if not exists
            'exchange_quantity': 1,
        })

    # if True:
    #     Model = client.model('product.product')
    #     # exchanges created through shopify
    #     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

    if True:
        service_line = {
            "order_line_id": line_id,
            "return_quantity": 0,
            "note": item['service'],
            "exchange_quantity": 1,
            "exchange_product": SERVICE_SKU[item['service']],
        }
        lines.append(service_line)
    payload = [{
        "channel_identifier":
        DT,  # Unique identifier for the return in the channel. This will be used as idempotency key to avoid duplication.
        "reference":
        f'repair-{item["order_name"]}',  # Return order reference, RMA
        "lines": lines,
        "warehouse": 57,
    }]
    payload = dumps(payload)
    response = requests.put(url, data=payload, headers=headers)
    if response.status_code != 500:
        print("success")
    # 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


#
#
# def create_fullfill_order_(item):
#     subdomain = 'aurate-sandbox'
#     token = '43cf9ddb7acc4ac69586b8f1081d65ab'
#     client = Client(subdomain, token)
#
#     CHANNEL_ID = 37
#
#     order_details = get_order_details(item)
#     SaleChannel = client.model('sale.channel')
#     record = SaleChannel.create_order(CHANNEL_ID, order_details)
#     print()
#
#
# def get_order_details(item):
#     a = item['address']
#     channel_identifier = str(int(item['DT']))
#     order_details = {
#         'channel_identifier': channel_identifier,
#         'reference': channel_identifier,
#         "confirmed_at": datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.000+00:00'),
#         # "confirmed_at": "2021-05-11T08:20:23.251-05:00",
#         'customer': {
#             'name': a['name'],
#             'contacts': [
#                 ['email', item['email']]
#             ],
#         },
#
#         'billing_address': {
#             'name': a['name'],
#             'address1': a['address1'],
#             'address2': a['address2'],
#             'city': a['city'],
#             'zip': '50001',
#             'subdivision_code': a['province_code'],
#             'country_code': a['country_code'],
#             'email': item['email'],
#             'phone': a['phone'].replace('(', '').replace(')', '').replace('-', '').replace(' ', ''),
#         },
#         'shipping_address': {
#             'name': a['name'],
#             'address1': a['address1'],
#             'address2': a['address2'],
#             'city': a['city'],
#             'zip': '',
#             'subdivision_code': a['province_code'],
#             'country_code': a['country_code'],
#             'email': item['email'],
#             'phone': a['phone'].replace('(', '').replace(')', '').replace('-', '').replace(' ', ''),
#         },
#         'sale_lines': [
#             {
#                 'sku': item['sku'],
#                 'quantity': 1,
#                 'unit_price': Decimal('1.00'),
#                 'amount': Decimal('1.00'),
#                 'comment': 'Repearment'
#             },
#         ],
#         'shipping_lines': [
#         ],
#         'amount': Decimal('1.00'),
#         'currency_code': 'USD',
#         'payment_term': 'NET 30',
#         'priority': 2,
#         'status': 'pending',
#         'financial_status': 'paid',
#         'fulfillment_status': 'unshipped',
#     }
#     return order_details
#
#
#
#
#
#
# def create_fullfill_return_(item):
#     subdomain = 'aurate-sandbox'
#     token = '43cf9ddb7acc4ac69586b8f1081d65ab'
#     client = Client(subdomain, token)
#
#     CHANNEL_ID = 37
#     item()
#     order_details = get_order(item)
#     SaleChannel = client.model('sale.channel')
#     return_created(body)
#     print()
# 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)
#     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({
#             "order_line_id": line_id,
#             # 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
#             "channel_identifier": body_l['line_item_id'],
#
#
#             # "note": "tracking_number " + body['tracking_number'],
#             "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": 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
コード例 #28
0
 def setUp(self):
     try:
         self.client = Client('fulfil_demo', os.environ['FULFIL_API_KEY'])
     except KeyError:
         self.fail('No FULFIL_API_KEY in environment')
コード例 #29
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from decimal import Decimal

from fulfil_client import Client

client = Client('<subdomain>', '<api_key>')

# ==========================
# Creating Product Template
# ==========================

Template = client.model('product.template')

iphone, = Template.create([{
    'name': 'iPhone',
    'account_category': True,
}])

# =================
# Creating Products
# =================

Product = client.model('product.product')

iphone6, = Product.create([{
    'template': iphone['id'],
    'variant_name': 'iPhone 6',
    'code': 'IPHONE-6',
    'list_price': Decimal('699'),
    'cost_price': Decimal('599'),