trytonpsk-sale_web_channel/shopify.py

791 lines
32 KiB
Python
Raw Normal View History

2020-10-16 16:46:59 +02:00
# -*- coding: UTF-8 -*-
# This file is part electronic_mail_template module for Tryton.
# The COPYRIGHT file at the top level of this repository contains
# the full copyright notices and license terms.
from decimal import Decimal
from trytond.pool import Pool
from itertools import chain
from trytond.transaction import Transaction
import requests
from urllib.parse import urlencode
from datetime import datetime, date
2022-03-02 21:38:45 +01:00
from .web_channel import SaleWebChannel
2020-10-16 16:46:59 +02:00
import json
import base64
import hmac
import hashlib
2020-10-16 16:46:59 +02:00
HEADERS = {
'Accept': 'application/json',
'Content-type': 'application/json'
}
2023-12-02 15:34:42 +01:00
# class Shopify(SaleWebChannel):
# 'Shopify'
# __name__ = 'sale.web_channel.shopify'
# @classmethod
# def __setup__(cls):
# super(Shopify, cls).__setup__()
# def _get_context(self):
# print(self)
# return {
# 'company': self.company.id,
# 'user': self.user.id,
# 'shops': [self.shop.id],
# 'shop': self.shop.id,
# 'language': 'es'
# }
# # def _get_user(self):
# # User = Pool().get('res.user')
# # user, = User.search(
# # ('login', '=', 'shopify')
# # )
# # return user
# def _create_product(self, codes, line={}):
# pool = Pool()
# Product = pool.get('product.product')
# Template = pool.get('product.template')
# description = line['variant_title']
# list_price = Decimal(str(round(float(line['price'])/1.19, 2)))
# sale_price_w_tax = Decimal(str(round(Decimal(line['price']), 2)))
# create_template = {
# 'name': line['title'],
# 'list_price': list_price,
# 'sale_price_w_tax': sale_price_w_tax,
# 'type': 'goods',
# 'salable': True,
# 'purchasable': True,
# 'purchase_uom': 1,
# 'sale_uom': 1,
# 'default_uom': 1,
# 'account_category': 7,
# 'code': codes[0],
# }
# template, = Template.create([create_template])
# create_product = []
# for code in codes:
# create_product.append({
# 'code': code,
# 'description': description,
# 'template': template.id
# })
# return Product.create(create_product)
# def _create_party(self, customer):
# _pool = Pool()
# City = _pool.get('party.city_code')
# Party = _pool.get('party.party')
# PartyObligationTax = _pool.get('party.obligation_tax')
# email = customer['email']
# shipment_address, phone, city = '', '', None
# if customer.get('default_address'):
# default_address = customer['default_address']
# shipment_address = default_address['address1']
# phone = default_address['phone'] or '000'
# city_name = default_address['city']
# if city_name:
# cities = City.search([
# ('name', '=', city_name)
# ])
# if cities:
# city = cities[0]
# customer_name = customer['first_name'] + ' ' + customer['last_name']
# create_customer = {
# 'id_reference': str(customer['id']),
# 'name': customer_name.upper(),
# 'type_document': '13',
# 'id_number': default_address['company'],
# 'addresses': [('create', [{
# 'street': shipment_address,
# }])],
# 'contact_mechanisms': [
# ('create', [
# {'type': 'phone', 'value': phone.replace(" ","")},
# {'type': 'email', 'value': email},
# ])
# ]
# }
# if not city:
# city = City(149)
# create_customer['addresses'][0][1][0]['department_code'] = city.department.id
# create_customer['addresses'][0][1][0]['city_code'] = city.id
# party, = Party.create([create_customer])
# PartyObligationTax.create([{
# 'party': party.id,
# 'obligation_fiscal': 6,
# }])
# return party
# # def _return_sale(self, sale):
# # pool = Pool()
# # Sale = pool.get('sale.sale')
# # Date = pool.get('ir.date')
# # ctx = self._get_context()
# # dev_sales = []
# # sales = [sale]
# # if sale.pack_id:
# # sales = Sale.search([
# # ('pack_id', '=', sale.pack_id)
# # ])
# # with Transaction().set_context(ctx):
# # return_sales = Sale.copy(sales)
# # for return_sale, sale in zip(return_sales, sales):
# # return_sale.origin = sale
# # return_sale.reference = sale.reference
# # return_sale.state = 'draft'
# # return_sale.sale_date = Date.today()
# # if sale.invoice_type == '1':
# # return_sale.invoice_type = '91'
# # for line in return_sale.lines:
# # if line.type == 'line':
# # line.quantity *= -1
# # line.save()
# # if return_sale.untaxed_amount_cache:
# # return_sale.untaxed_amount_cache *= -1
# # if return_sale.tax_amount_cache:
# # return_sale.tax_amount_cache *= -1
# # if return_sale.total_amount_cache:
# # return_sale.total_amount_cache *= -1
# # return_sale.save()
# # Sale.quote([return_sale])
# # Sale.write([return_sale], {'state': 'confirmed'})
# # dev_sales.append(return_sale)
# # return dev_sales
# def _create_sale(self, sale_):
# print('ingresa a crear venta')
# _pool = Pool()
# Sale = _pool.get('sale.sale')
# sales = Sale.search([
# ('reference', '=', str(sale_['id']))
# ])
# if sales:
# return False
# SaleLine = _pool.get('sale.line')
# Party = _pool.get('party.party')
# User = _pool.get('res.user')
# if sale_.get('customer'):
# customer = sale_['customer']
# dom_party = [('id_number', '=', str(customer['default_address']['company']))]
# parties = Party.search(dom_party)
# if parties:
# party = parties[0]
# else:
# party = self._create_party(customer)
# create_lines = []
# ctx = self._get_context()
# user_ = User(ctx['user'])
# date_created = sale_['created_at'].split('T')
# year, month, day = date_created[0].split('-')
# sale_date = date(int(year), int(month), int(day))
# with Transaction().set_user(ctx['user']):
# comment = ''
# try:
# comment = 'GUIA DE ENVIO NO. ' + sale_['fulfillments'][0].get('tracking_number', '')\
# if sale_['fulfillment_status'] == 'fulfilled' and sale_['fulfillments'] else ''
# except:
# pass
# sale, = Sale.create([{
# 'payment_term': 1,
# 'party': party.id,
# 'sale_date': sale_date,
# 'comment': comment,
# 'state': 'draft',
# 'company': ctx['company'],
# 'currency': user_.company.currency.id,
# 'shop': user_.shop.id,
# 'reference': str(sale_['id']),
# 'invoice_address': Party.address_get(party, type='invoice'),
# 'shipment_address': Party.address_get(party, type='delivery'),
# 'description': 'VENTA SHOPIFY ' + sale_['name'],
# 'channel': self.id,
# 'invoice_type': self.invoice_type,
# 'pack_id': ''
# }])
# with Transaction().set_context(ctx):
# create_lines = self.get_sale_lines(sale_, sale)
# SaleLine.create(create_lines)
# sale.untaxed_amount_cache = sale.untaxed_amount
# if sale_['cancel_reason'] is not None:
# sale.state = 'cancelled'
# else:
# Sale.quote([sale])
# sale.save()
# if sale_['fulfillment_status'] == 'fulfilled':
# self.order_fulfilled(sale_, [sale])
# print('*******************', sale.state)
# return sale
# def get_sale_lines(self, sale_, sale, products_refund=[]):
# pool = Pool()
# Product = pool.get('product.product')
# sale_items = sale_['line_items']
# products_refund = {}
# if sale_.get('refunds'):
# for refunds in sale_['refunds']:
# for line_items in refunds['refund_line_items']:
# sku_code = line_items['line_item']['sku']
# quantity = line_items['quantity']
# if sku_code.count('+') > 0:
# codes = sku_code.split('+')
# for code in codes:
# if code not in products_refund.keys():
# products_refund[code] = quantity
# else:
# products_refund[code] += quantity
# else:
# if sku_code not in products_refund.keys():
# products_refund[sku_code] = quantity
# else:
# products_refund[sku_code] += quantity
# create_lines = []
# for line in sale_items:
# if line['title'] == 'Tip':
# if self.tip_product:
# product = self.tip_product
# total_tip = line['price']
# create_lines.append({
# 'sale': sale.id,
# 'type': 'line',
# 'unit': product.default_uom.id,
# 'quantity': 1,
# 'unit_price': Decimal(total_tip),
# 'base_price': Decimal(total_tip),
# 'unit_price_full': Decimal(total_tip),
# 'product': product.id,
# 'description': 'BONIFICACION',
# })
# else:
# sku_code = line['sku']
# if sku_code.count('+') > 0:
# codes = sku_code.split('+')
# line['price'] = round(Decimal(line['price']) / 2, 2)
# discount = round(sum([Decimal(n['amount']) for n in line['discount_allocations']]) / 2, 2)
# else:
# codes = [sku_code]
# discount = round(sum([Decimal(n['amount']) for n in line['discount_allocations']]))
# products = Product.search([
# ('code', 'in', codes),
# ('active', '=', True)
# ])
# description = ''
# if not products:
# products = self._create_product(codes, line)
# for product in products:
# quantity = line['quantity']
# if products_refund and product.code in products_refund.keys():
# if products_refund[product.code] < quantity:
# quantity -= products_refund[product.code]
# else:
# continue
# Tax = pool.get('account.tax')
# un_price = Tax.reverse_compute((Decimal(line['price']) - Decimal(discount)),
# product.customer_taxes_used)
# create_lines.append({
# 'sale': sale.id,
# 'type': 'line',
# 'unit': product.default_uom.id,
# 'quantity': quantity,
# 'base_price': round(Decimal(un_price), 3),
# 'unit_price': round(Decimal(un_price), 3),
# 'unit_price_full': round(Decimal(line['price']),2),
# 'product': product.id,
# 'taxes': [('add', product.customer_taxes_used)],
# 'description': description,
# })
# if self.freight_product and len(sale_['shipping_lines']) > 0:
# product = self.freight_product
# shipping_amount = sale_['shipping_lines'][0]['price']
# create_lines.append({
# 'sale': sale.id,
# 'type': 'line',
# 'unit': product.default_uom.id,
# 'quantity': 1,
# 'base_price': Decimal(shipping_amount),
# 'unit_price': Decimal(shipping_amount),
# 'unit_price_full': Decimal(shipping_amount),
# 'product': product.id,
# 'description': 'FLETE',
# })
# return create_lines
# def order_updated(self, data, sales):
# sale = sales[0]
# pool = Pool()
# SaleLine = pool.get('sale.line')
# Sale = pool.get('sale.sale')
# lines_to_remove = [line for line in sale.lines]
# Sale.draft([sale])
# SaleLine.delete(lines_to_remove)
# create_lines = self.get_sale_lines(data, sale)
# SaleLine.create(create_lines)
# Sale.quote([sale])
# if data['fulfillment_status'] == 'fulfilled':
# self.order_fulfilled(data, [sale])
# return sale
# def order_cancelled(self, data, sales):
# pool = Pool()
# Sale = pool.get('sale.sale')
# sale = sales[0]
# Sale.draft([sale])
# Sale.cancel([sale])
# return sale
# def order_fulfilled(self, data, sales):
# pool = Pool()
# Sale = pool.get('sale.sale')
# sale = sales[0]
# response = False
# if sale.invoices:
# return response
# elif sale.state == 'quotation':
# Sale.confirm([sale])
# if len(sales) > 1:
# # channel.upload_note(sale, 'Error, al generar factura orden duplicada')
# return response
# if data.get('fulfillment_status') == 'fulfilled':
# track_number = ''
# try:
# track_number = str(data['fulfillments'][0]['tracking_number'])
# except:
# pass
# Sale.write([sale], {
# 'description': sale.description + ' - ' + data['fulfillment_status'],
# 'comment': 'GUIA DE ENVIO NO. ' + track_number,
# 'tracking_number': track_number
# })
# return sale
# @classmethod
# def get_response(cls, URI, params={}):
# response = requests.get(URI, headers=HEADERS, params=urlencode(params))
# return response
# @classmethod
# def verify_webhook_shopify(cls, data, hmac_header, secret):
# digest = hmac.new(secret.encode('utf-8'), data, hashlib.sha256).digest()
# genHmac = base64.b64encode(digest)
# return hmac.compare_digest(genHmac, hmac_header.encode('utf-8'))
# @classmethod
# def request_api(cls, request):
# response = {'status': 'error', 'msg': 'Fail in process !!!'}
# data = request.get_data()
# action_topic = request.headers.get('X-Shopify-Topic')
# domain_name = request.headers.get('X-Shopify-Shop-Domain')
# channels = cls.search([('host_name', '=', domain_name), ])
# channel = channels[0]
# hmac_header = request.headers.get('X-Shopify-Hmac-SHA256')
# verified = cls.verify_webhook_shopify(data, hmac_header, channel.secret_key)
# if verified:
# req = data.decode("utf-8")
# data = json.loads(req)
# if action_topic.count('create'):
# res = channel._create_sale(data)
# if res:
# response = {'status': 'ok', 'msg': 'Successfull create sale !!!'}
# else:
# order_id = data.get('id')
# Sale = Pool().get('sale.sale')
# sales = Sale.search([
# ('reference', '=', str(order_id))
# ])
# if not sales:
# return response
# if action_topic.count('fulfilled'):
# res = channel.order_fulfilled(data, sales)
# if res:
# response = {'status': 'ok', 'msg': 'Successfull process sale' + res.number+' in state' + res.state + '!!!' }
# elif action_topic.count('paid'):
# pass
# elif action_topic.count('updated'):
# res = channel.order_updated(data, sales)
# if res:
# response = {'status': 'ok', 'msg': 'Successfull update sale ' + res.number+' in state' + res.state + '!!!' }
# elif action_topic.count('cancelled'):
# res = channel.order_cancelled(data, sales)
# if res:
# response = {'status': 'ok', 'msg': 'Successfull cancel sale ' + res.number+' in state' + res.state + '!!!' }
# return response
class Shopify:
2020-10-16 16:46:59 +02:00
'Shopify'
2023-12-02 15:34:42 +01:00
def __init__(self, web_shop):
self.access_token = web_shop.access_token if web_shop.access_token else ''
self.generic_product = web_shop.generic_product
self.refresh_token = web_shop.refresh_token
self.id = web_shop.id
self.app_id = web_shop.app_id
self.secret_key = web_shop.secret_key
self.freight_product = web_shop.freight_product
2023-12-11 17:22:25 +01:00
self.invoice_type = web_shop.invoice_type
2020-10-16 16:46:59 +02:00
def _get_context(self):
2023-12-02 15:34:42 +01:00
user_ = self._get_user()
2020-10-16 16:46:59 +02:00
return {
2023-12-02 15:34:42 +01:00
'company': user_.company.id,
2023-12-11 17:22:25 +01:00
'user': user_.id,
2023-12-02 15:34:42 +01:00
'shops': [user_.shop.id],
'shop': user_.shop.id,
2020-10-16 16:46:59 +02:00
'language': 'es'
}
2023-12-02 15:34:42 +01:00
def _get_user(self):
User = Pool().get('res.user')
user, = User.search(
('login', '=', 'shopify')
)
return user
2020-10-16 16:46:59 +02:00
def _create_product(self, codes, line={}):
pool = Pool()
Product = pool.get('product.product')
Template = pool.get('product.template')
description = line['variant_title']
2022-08-30 22:51:13 +02:00
list_price = Decimal(str(round(float(line['price'])/1.19, 2)))
sale_price_w_tax = Decimal(str(round(Decimal(line['price']), 2)))
2020-10-16 16:46:59 +02:00
create_template = {
'name': line['title'],
2022-08-16 21:19:05 +02:00
'list_price': list_price,
'sale_price_w_tax': sale_price_w_tax,
2020-10-16 16:46:59 +02:00
'type': 'goods',
'salable': True,
'purchasable': True,
'purchase_uom': 1,
'sale_uom': 1,
'default_uom': 1,
'account_category': 7,
2022-08-30 22:48:33 +02:00
'code': codes[0],
2020-10-16 16:46:59 +02:00
}
template, = Template.create([create_template])
create_product = []
for code in codes:
create_product.append({
'code': code,
'description': description,
'template': template.id
})
return Product.create(create_product)
def _create_party(self, customer):
_pool = Pool()
City = _pool.get('party.city_code')
Party = _pool.get('party.party')
PartyObligationTax = _pool.get('party.obligation_tax')
email = customer['email']
shipment_address, phone, city = '', '', None
if customer.get('default_address'):
default_address = customer['default_address']
shipment_address = default_address['address1']
2021-02-26 20:49:52 +01:00
phone = default_address['phone'] or '000'
2020-10-16 16:46:59 +02:00
city_name = default_address['city']
if city_name:
cities = City.search([
('name', '=', city_name)
])
if cities:
city = cities[0]
customer_name = customer['first_name'] + ' ' + customer['last_name']
create_customer = {
'id_reference': str(customer['id']),
'name': customer_name.upper(),
'type_document': '13',
'id_number': default_address['company'],
'addresses': [('create', [{
'street': shipment_address,
}])],
'contact_mechanisms': [
('create', [
2021-02-26 20:49:52 +01:00
{'type': 'phone', 'value': phone.replace(" ","")},
2020-10-16 16:46:59 +02:00
{'type': 'email', 'value': email},
])
]
}
if not city:
city = City(149)
create_customer['addresses'][0][1][0]['department_code'] = city.department.id
create_customer['addresses'][0][1][0]['city_code'] = city.id
party, = Party.create([create_customer])
PartyObligationTax.create([{
'party': party.id,
'obligation_fiscal': 6,
}])
return party
def _create_sale(self, sale_):
_pool = Pool()
Sale = _pool.get('sale.sale')
sales = Sale.search([
('reference', '=', str(sale_['id']))
])
if sales:
return False
SaleLine = _pool.get('sale.line')
Party = _pool.get('party.party')
User = _pool.get('res.user')
if sale_.get('customer'):
customer = sale_['customer']
dom_party = [('id_number', '=', str(customer['default_address']['company']))]
parties = Party.search(dom_party)
if parties:
party = parties[0]
else:
party = self._create_party(customer)
create_lines = []
ctx = self._get_context()
user_ = User(ctx['user'])
date_created = sale_['created_at'].split('T')
year, month, day = date_created[0].split('-')
sale_date = date(int(year), int(month), int(day))
with Transaction().set_user(ctx['user']):
2022-08-16 21:19:05 +02:00
comment = ''
try:
comment = 'GUIA DE ENVIO NO. ' + sale_['fulfillments'][0].get('tracking_number', '')\
if sale_['fulfillment_status'] == 'fulfilled' and sale_['fulfillments'] else ''
except:
pass
2020-10-16 16:46:59 +02:00
sale, = Sale.create([{
'payment_term': 1,
'party': party.id,
'sale_date': sale_date,
2022-08-16 21:19:05 +02:00
'comment': comment,
2020-10-16 16:46:59 +02:00
'state': 'draft',
'company': ctx['company'],
'currency': user_.company.currency.id,
'shop': user_.shop.id,
'reference': str(sale_['id']),
'invoice_address': Party.address_get(party, type='invoice'),
'shipment_address': Party.address_get(party, type='delivery'),
2021-05-06 23:47:55 +02:00
'description': 'VENTA SHOPIFY ' + sale_['name'],
2023-12-11 17:22:25 +01:00
'web_shop': self.id,
'web_id': str(sale_['id']),
2020-10-16 16:46:59 +02:00
'invoice_type': self.invoice_type,
'pack_id': ''
}])
with Transaction().set_context(ctx):
2021-04-24 16:23:07 +02:00
create_lines = self.get_sale_lines(sale_, sale)
2020-10-16 16:46:59 +02:00
SaleLine.create(create_lines)
sale.untaxed_amount_cache = sale.untaxed_amount
2021-04-24 16:23:07 +02:00
if sale_['cancel_reason'] is not None:
2021-09-04 16:27:03 +02:00
sale.state = 'cancelled'
2021-02-20 17:01:40 +01:00
else:
Sale.quote([sale])
2020-10-16 16:46:59 +02:00
sale.save()
2021-05-06 23:47:55 +02:00
if sale_['fulfillment_status'] == 'fulfilled':
2021-05-10 22:54:32 +02:00
self.order_fulfilled(sale_, [sale])
2021-05-06 23:47:55 +02:00
print('*******************', sale.state)
2020-10-16 16:46:59 +02:00
return sale
2021-05-10 16:32:11 +02:00
def get_sale_lines(self, sale_, sale, products_refund=[]):
2021-04-24 16:23:07 +02:00
pool = Pool()
Product = pool.get('product.product')
sale_items = sale_['line_items']
2021-05-10 16:32:11 +02:00
products_refund = {}
if sale_.get('refunds'):
for refunds in sale_['refunds']:
2021-05-11 23:40:20 +02:00
for line_items in refunds['refund_line_items']:
2021-05-11 23:46:42 +02:00
sku_code = line_items['line_item']['sku']
2021-05-13 00:32:40 +02:00
quantity = line_items['quantity']
2021-05-11 23:40:20 +02:00
if sku_code.count('+') > 0:
codes = sku_code.split('+')
for code in codes:
2021-05-13 00:32:40 +02:00
if code not in products_refund.keys():
products_refund[code] = quantity
else:
products_refund[code] += quantity
2021-05-11 23:40:20 +02:00
else:
2021-05-13 00:32:40 +02:00
if sku_code not in products_refund.keys():
products_refund[sku_code] = quantity
else:
products_refund[sku_code] += quantity
2021-04-24 16:23:07 +02:00
create_lines = []
for line in sale_items:
if line['title'] == 'Tip':
if self.tip_product:
product = self.tip_product
total_tip = line['price']
create_lines.append({
'sale': sale.id,
'type': 'line',
'unit': product.default_uom.id,
'quantity': 1,
'unit_price': Decimal(total_tip),
2022-08-31 15:51:11 +02:00
'base_price': Decimal(total_tip),
2021-04-24 16:23:07 +02:00
'unit_price_full': Decimal(total_tip),
'product': product.id,
'description': 'BONIFICACION',
})
else:
sku_code = line['sku']
if sku_code.count('+') > 0:
codes = sku_code.split('+')
line['price'] = round(Decimal(line['price']) / 2, 2)
discount = round(sum([Decimal(n['amount']) for n in line['discount_allocations']]) / 2, 2)
else:
codes = [sku_code]
discount = round(sum([Decimal(n['amount']) for n in line['discount_allocations']]))
products = Product.search([
('code', 'in', codes),
('active', '=', True)
])
description = ''
if not products:
products = self._create_product(codes, line)
for product in products:
2021-05-10 16:32:11 +02:00
quantity = line['quantity']
if products_refund and product.code in products_refund.keys():
if products_refund[product.code] < quantity:
quantity -= products_refund[product.code]
else:
continue
2021-04-24 16:23:07 +02:00
Tax = pool.get('account.tax')
2021-05-06 16:51:41 +02:00
un_price = Tax.reverse_compute((Decimal(line['price']) - Decimal(discount)),
2021-04-24 16:23:07 +02:00
product.customer_taxes_used)
create_lines.append({
'sale': sale.id,
'type': 'line',
'unit': product.default_uom.id,
2021-05-10 16:32:11 +02:00
'quantity': quantity,
2022-08-16 21:19:05 +02:00
'base_price': round(Decimal(un_price), 3),
2021-04-24 16:23:07 +02:00
'unit_price': round(Decimal(un_price), 3),
'unit_price_full': round(Decimal(line['price']),2),
'product': product.id,
'taxes': [('add', product.customer_taxes_used)],
'description': description,
})
2021-07-03 15:36:54 +02:00
if self.freight_product and len(sale_['shipping_lines']) > 0:
2021-04-24 16:23:07 +02:00
product = self.freight_product
shipping_amount = sale_['shipping_lines'][0]['price']
create_lines.append({
'sale': sale.id,
'type': 'line',
'unit': product.default_uom.id,
'quantity': 1,
2022-08-31 15:51:11 +02:00
'base_price': Decimal(shipping_amount),
2021-04-24 16:23:07 +02:00
'unit_price': Decimal(shipping_amount),
'unit_price_full': Decimal(shipping_amount),
'product': product.id,
'description': 'FLETE',
})
return create_lines
2021-04-24 16:52:45 +02:00
def order_updated(self, data, sales):
sale = sales[0]
pool = Pool()
SaleLine = pool.get('sale.line')
Sale = pool.get('sale.sale')
2021-04-24 16:57:52 +02:00
lines_to_remove = [line for line in sale.lines]
2021-04-24 16:52:45 +02:00
Sale.draft([sale])
2021-04-24 16:57:52 +02:00
SaleLine.delete(lines_to_remove)
2021-05-10 16:32:11 +02:00
2021-04-24 16:52:45 +02:00
create_lines = self.get_sale_lines(data, sale)
SaleLine.create(create_lines)
Sale.quote([sale])
2021-05-07 01:15:06 +02:00
if data['fulfillment_status'] == 'fulfilled':
2021-05-10 22:54:32 +02:00
self.order_fulfilled(data, [sale])
2021-04-24 16:52:45 +02:00
return sale
def order_cancelled(self, data, sales):
pool = Pool()
Sale = pool.get('sale.sale')
2021-04-24 17:06:51 +02:00
sale = sales[0]
2021-04-24 18:22:04 +02:00
Sale.draft([sale])
2021-04-24 17:06:51 +02:00
Sale.cancel([sale])
2021-05-07 00:13:47 +02:00
return sale
2021-04-24 16:52:45 +02:00
def order_fulfilled(self, data, sales):
pool = Pool()
Sale = pool.get('sale.sale')
sale = sales[0]
response = False
if sale.invoices:
return response
2021-05-07 00:13:47 +02:00
elif sale.state == 'quotation':
2021-04-24 17:06:51 +02:00
Sale.confirm([sale])
2021-04-24 16:52:45 +02:00
if len(sales) > 1:
# channel.upload_note(sale, 'Error, al generar factura orden duplicada')
return response
if data.get('fulfillment_status') == 'fulfilled':
2022-08-16 21:19:05 +02:00
track_number = ''
try:
track_number = str(data['fulfillments'][0]['tracking_number'])
except:
pass
2021-04-24 16:52:45 +02:00
Sale.write([sale], {
'description': sale.description + ' - ' + data['fulfillment_status'],
2022-08-16 21:19:05 +02:00
'comment': 'GUIA DE ENVIO NO. ' + track_number,
'tracking_number': track_number
2021-04-24 16:52:45 +02:00
})
2021-05-07 00:13:47 +02:00
return sale
2021-04-24 16:52:45 +02:00
2020-10-16 16:46:59 +02:00
@classmethod
def get_response(cls, URI, params={}):
response = requests.get(URI, headers=HEADERS, params=urlencode(params))
return response
@classmethod
def verify_webhook_shopify(cls, data, hmac_header, secret):
digest = hmac.new(secret.encode('utf-8'), data, hashlib.sha256).digest()
genHmac = base64.b64encode(digest)
return hmac.compare_digest(genHmac, hmac_header.encode('utf-8'))
2020-10-16 16:46:59 +02:00
@classmethod
def request_api(cls, request):
2020-10-16 16:46:59 +02:00
response = {'status': 'error', 'msg': 'Fail in process !!!'}
data = request.get_data()
action_topic = request.headers.get('X-Shopify-Topic')
2021-06-29 23:50:04 +02:00
domain_name = request.headers.get('X-Shopify-Shop-Domain')
channels = cls.search([('host_name', '=', domain_name), ])
channel = channels[0]
hmac_header = request.headers.get('X-Shopify-Hmac-SHA256')
verified = cls.verify_webhook_shopify(data, hmac_header, channel.secret_key)
if verified:
req = data.decode("utf-8")
data = json.loads(req)
if action_topic.count('create'):
res = channel._create_sale(data)
2021-04-24 16:47:17 +02:00
if res:
response = {'status': 'ok', 'msg': 'Successfull create sale !!!'}
else:
order_id = data.get('id')
Sale = Pool().get('sale.sale')
sales = Sale.search([
('reference', '=', str(order_id))
])
if not sales:
return response
if action_topic.count('fulfilled'):
res = channel.order_fulfilled(data, sales)
if res:
response = {'status': 'ok', 'msg': 'Successfull process sale' + res.number+' in state' + res.state + '!!!' }
elif action_topic.count('paid'):
pass
elif action_topic.count('updated'):
res = channel.order_updated(data, sales)
if res:
response = {'status': 'ok', 'msg': 'Successfull update sale ' + res.number+' in state' + res.state + '!!!' }
elif action_topic.count('cancelled'):
res = channel.order_cancelled(data, sales)
if res:
response = {'status': 'ok', 'msg': 'Successfull cancel sale ' + res.number+' in state' + res.state + '!!!' }
return response