Woocommerce and some fixes

This commit is contained in:
Diego Calvo
2021-04-08 15:12:05 +02:00
parent 06bababfa6
commit 2ecab694b9
10 changed files with 1456 additions and 26 deletions

View File

@@ -1,7 +1,25 @@
from rest_framework import permissions
class IsCreator(permissions.BasePermission):
class IsCompanyOwner(permissions.BasePermission):
"""
Grant permission if request.user.company same as obj.id
"""
def has_object_permission(self, request, view, obj):
if obj is not None:
# allow if authenticated and method is safe
if request.method in permissions.SAFE_METHODS:
return True
# admins always have permission
if request.user.is_staff is True:
return True
# permission if user is the object's creator
return obj == request.user.company
return False
class IsProductOwner(permissions.BasePermission):
"""
Grant permission if request.user same as obj.creator
"""
@@ -16,10 +34,9 @@ class IsCreator(permissions.BasePermission):
if request.user.is_staff is True:
return True
# permission if user is the object's creator
return obj.creator == request.user
return obj.company == request.user.company
return False
class IsStaff(permissions.BasePermission):
"""
Grant permission if request.user.is_staff is True

View File

@@ -47,6 +47,7 @@ urlpatterns = [
path('api/v1/companies/sample/', company_views.random_company_sample , name='company-sample'),
path('api/v1/search/companies/', company_views.CompanySearchViewSet.as_view({'get': 'list'}) , name='company-search'),
path('api/v1/purchase_email/', product_views.purchase_email, name='purchase-email'),
path('api/v1/sync_shop/', product_views.sync_shop, name='purchase-email'),
path('api/v1/products/all_categories/', product_views.all_categories, name='all-categories'),
path('api/v1/stats/me/', stat_views.track_user, name='user-tracker'),
path('api/v1/autocomplete/category-tag/', product_views.CategoryTagAutocomplete.as_view(), name='category-autocomplete'),

View File

@@ -19,7 +19,7 @@ from companies.models import Company
from companies.serializers import CompanySerializer
from utils.tag_filters import CompanyTagFilter
from rest_framework import filters
from back_latienda.permissions import IsCreator, IsSiteAdmin
from back_latienda.permissions import IsCompanyOwner, IsSiteAdmin
from utils import woocommerce
@@ -27,7 +27,7 @@ from utils import woocommerce
class CompanySearchViewSet(viewsets.ModelViewSet):
queryset = Company.objects.filter(is_validated=True).order_by('-created')
serializer_class = CompanySerializer
permission_classes = [IsAuthenticatedOrReadOnly, IsCreator]
permission_classes = [IsAuthenticatedOrReadOnly, IsCompanyOwner]
filter_backends = (filters.SearchFilter, )
# search_fields = ['company_name__unaccent__icontains', 'short_name__unaccent__icontains']
search_fields = ['@company_name', '@short_name']
@@ -36,7 +36,7 @@ class CompanySearchViewSet(viewsets.ModelViewSet):
class CompanyViewSet(viewsets.ModelViewSet):
queryset = Company.objects.filter(is_validated=True).order_by('-created')
serializer_class = CompanySerializer
permission_classes = [IsAuthenticatedOrReadOnly, IsCreator]
permission_classes = [IsAuthenticatedOrReadOnly, IsCompanyOwner]
filterset_class = CompanyTagFilter
def perform_create(self, serializer):

View File

@@ -57,7 +57,7 @@ class CustomUser(AbstractBaseUser, PermissionsMixin):
notify = models.BooleanField('Notificar', default=False, null=True)
provider = models.CharField('Proveedor', max_length=1000, blank=True, null=True) # red social de registro
email_verified = models.BooleanField('Email verificado', default=False, null=True)
company = models.ForeignKey(Company, null=True, on_delete=models.DO_NOTHING, related_name='custom_user')
company = models.ForeignKey(Company, null=True, blank=True, on_delete=models.DO_NOTHING, related_name='custom_user')
is_active = models.BooleanField('Activo', default=True)
is_staff = models.BooleanField('Empleado',default=False )

View File

@@ -1,6 +1,6 @@
from rest_framework import viewsets
from back_latienda.permissions import IsCreator, ReadOnly
from back_latienda.permissions import ReadOnly
from . import models
from . import serializers

View File

@@ -10,9 +10,12 @@ from back_latienda.permissions import IsStaff
class HistorySyncViewSet(viewsets.ModelViewSet):
queryset = HistorySync.objects.all()
model = HistorySync
serializer_class = HistorySyncLogSerializer
permission_classes = [IsAuthenticated,]
def perform_create(self, serializer):
serializer.save(creator=self.request.user)
def get_queryset(self):
return self.model.objects.filter(company=self.request.user.company).order_by('-created')

View File

@@ -30,8 +30,9 @@ from products.models import Product, CategoryTag
from products.serializers import ProductSerializer, TagFilterSerializer, SearchResultSerializer
from companies.models import Company
from stats.models import StatsLog
from back_latienda.permissions import IsCreator, IsSiteAdmin, ReadOnly
from back_latienda.permissions import IsProductOwner, IsSiteAdmin, ReadOnly
from .utils import extract_search_filters, ranked_product_search, product_loader, get_related_products
from utils.woocommerce import migrate_shop_products
from utils.tag_serializers import TaggitSerializer
from utils.tag_filters import ProductTagFilter, ProductOrderFilter
@@ -48,7 +49,7 @@ logging.basicConfig(
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.filter(active=True).order_by('-created')
serializer_class = ProductSerializer
permission_classes = [IsAuthenticatedOrReadOnly, IsCreator]
permission_classes = [IsAuthenticatedOrReadOnly, IsProductOwner]
filter_backends = [DjangoFilterBackend, OrderingFilter]
filterset_class = ProductTagFilter
@@ -71,7 +72,7 @@ class MyProductsViewSet(viewsets.ModelViewSet):
"""
model = Product
serializer_class = ProductSerializer
permission_classes = [IsAuthenticated]
permission_classes = [IsAuthenticated, IsProductOwner]
def get_queryset(self):
return self.model.objects.filter(company=self.request.user.company).order_by('-created')
@@ -403,3 +404,32 @@ def all_categories(request):
all_categories.append(instance.name)
return Response(data=all_categories)
@api_view(['POST'])
@permission_classes([IsAuthenticated,])
def sync_shop(request):
print(request.data)
url = request.data.get('url')
key = request.data.get('key')
secret = request.data.get('secret')
print(f"Starting migration...")
response = migrate_shop_products(url, key, secret, request.user )
print(f"Products created: {len(response['new_products'])}")
print(response["error"])
if response["error"]:
message = render_to_string('sync_failed.html', {})
# send email to company
subject = "Estado de la sincronización"
email = EmailMessage(subject, message, to=[request.user.email])
email.content_subtype = "html"
email.send()
else:
message = render_to_string('sync_success.html', {
'new_products': len(response['new_products'])
})
# send email to company
subject = "Estado de la sincronización"
email = EmailMessage(subject, message, to=[request.user.email])
email.content_subtype = "html"
email.send()
return Response()

678
templates/sync_failed.html Normal file
View File

@@ -0,0 +1,678 @@
<!DOCTYPE html>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
>
<head>
<title> </title>
<!--[if !mso]><!-- -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!--<![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
#outlook a {
padding: 0;
}
body {
margin: 0;
padding: 0;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
table,
td {
border-collapse: collapse;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
}
img {
border: 0;
height: auto;
line-height: 100%;
outline: none;
text-decoration: none;
-ms-interpolation-mode: bicubic;
}
p {
display: block;
margin: 13px 0;
}
</style>
<!--[if mso]>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG />
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
<![endif]-->
<!--[if lte mso 11]>
<style type="text/css">
.mj-outlook-group-fix {
width: 100% !important;
}
</style>
<![endif]-->
<!--[if !mso]><!-->
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap"
rel="stylesheet"
type="text/css"
/>
<link
href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;700&display=swap"
rel="stylesheet"
type="text/css"
/>
<style type="text/css">
@import url(https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap);
@import url(https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;700&display=swap);
</style>
<!--<![endif]-->
<style type="text/css">
@media only screen and (min-width: 480px) {
.mj-column-per-100 {
width: 100% !important;
max-width: 100%;
}
.mj-column-per-50 {
width: 50% !important;
max-width: 50%;
}
}
</style>
<style type="text/css">
@media only screen and (max-width: 480px) {
table.mj-full-width-mobile {
width: 100% !important;
}
td.mj-full-width-mobile {
width: auto !important;
}
}
</style>
</head>
<body style="background-color: #8cead8">
<div style="background-color: #8cead8">
<!--[if mso | IE]>
<table
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
>
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 600px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #ffffff;
background-color: #ffffff;
width: 100%;
"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 20px 0;
padding-bottom: 20px;
padding-top: 20px;
text-align: center;
"
>
<!--[if mso | IE]>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td
class="" style="vertical-align:top;width:600px;"
>
<![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
>
<tr>
<td
align="center"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 10px;
padding-right: 0px;
padding-bottom: 10px;
padding-left: 0px;
word-break: break-word;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
border-collapse: collapse;
border-spacing: 0px;
"
>
<tbody>
<tr>
<td
style="
width: 250px;
"
>
<a
href="https://latienda.coop/"
target="_blank"
>
<img
alt=""
height="auto"
width="25"
align="left"
src="https://latienda.coop/_nuxt/img/latienda-logo.dea6549.png"
style="
border: none;
display: block;
outline: none;
text-decoration: none;
height: auto;
width: 100%;
font-size: 13px;
"
/>
</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<table
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
>
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 600px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #ffffff;
background-color: #ffffff;
width: 100%;
"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 20px 0;
padding-bottom: 0px;
padding-top: 0;
text-align: center;
"
>
<!--[if mso | IE]>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td
class="" style="vertical-align:top;width:600px;"
>
<![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
>
<tr>
<td
align="center"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 28px;
padding-right: 25px;
padding-bottom: 18px;
padding-left: 25px;
word-break: break-word;
"
>
<div
style="
font-family: Poppins,
Arial, sans-serif;
font-size: 20px;
font-weight: bold;
line-height: 1;
text-align: center;
color: #374493;
"
>
Se ha producido un error en la sincronización
</div>
</td>
</tr>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<table
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
>
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 600px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #ffffff;
background-color: #ffffff;
width: 100%;
"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 20px 0;
padding-bottom: 5px;
padding-top: 0;
text-align: center;
"
>
<!--[if mso | IE]>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td
class="" style="vertical-align:top;width:600px;"
>
<![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
>
<tr>
<td
align="center"
style="
font-size: 0px;
padding: 10px 25px;
padding-right: 0px;
padding-left: 0px;
word-break: break-word;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
border-collapse: collapse;
border-spacing: 0px;
"
>
<tbody>
<tr>
<td
style="
width: 250px;
"
></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr></tr>
<tr>
<td
align="center"
width="50"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 28px;
padding-right: 25px;
padding-bottom: 28px;
padding-left: 25px;
word-break: break-word;
"
>
<p
style="
font-family: Noto Sans,
sans-serif;
font-size: 17px;
line-height: 1.5;
text-align: center;
color: #374493;
margin: 0 50px;
"
>
Tu sincronización de productos desde tu tienda online ha finalizado con un error.
<br>
<br>
Comprueba tus credenciales y URL e inténtalo de nuevo. Si el error persiste, contacta con nosotros.
<br>
<br>
</p>
</td>
</tr>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<table
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
>
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 600px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #ffffff;
background-color: #ffffff;
width: 100%;
"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 20px 0;
padding-bottom: 15px;
text-align: center;
"
>
<!--[if mso | IE]>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td
class="" style="vertical-align:top;width:300px;"
>
<![endif]-->
<div
class="mj-column-per-50 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
></table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<table
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
>
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<!--[if mso | IE]>
</td>
</tr>
</table>
<table
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
>
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 600px;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
>
<tr>
<td
align="center"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 20px;
padding-right: 25px;
padding-bottom: 20px;
padding-left: 25px;
word-break: break-word;
"
>
<div
style="
font-family: Poppins, Arial, sans-serif;
font-size: 15px;
line-height: 1;
text-align: center;
color: #374493;
"
>
2021 La Tienda.coop
</div>
</td>
</tr>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</div>
</body>
</html>

678
templates/sync_success.html Normal file
View File

@@ -0,0 +1,678 @@
<!DOCTYPE html>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
>
<head>
<title> </title>
<!--[if !mso]><!-- -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!--<![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
#outlook a {
padding: 0;
}
body {
margin: 0;
padding: 0;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
table,
td {
border-collapse: collapse;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
}
img {
border: 0;
height: auto;
line-height: 100%;
outline: none;
text-decoration: none;
-ms-interpolation-mode: bicubic;
}
p {
display: block;
margin: 13px 0;
}
</style>
<!--[if mso]>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG />
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
<![endif]-->
<!--[if lte mso 11]>
<style type="text/css">
.mj-outlook-group-fix {
width: 100% !important;
}
</style>
<![endif]-->
<!--[if !mso]><!-->
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap"
rel="stylesheet"
type="text/css"
/>
<link
href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;700&display=swap"
rel="stylesheet"
type="text/css"
/>
<style type="text/css">
@import url(https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap);
@import url(https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;700&display=swap);
</style>
<!--<![endif]-->
<style type="text/css">
@media only screen and (min-width: 480px) {
.mj-column-per-100 {
width: 100% !important;
max-width: 100%;
}
.mj-column-per-50 {
width: 50% !important;
max-width: 50%;
}
}
</style>
<style type="text/css">
@media only screen and (max-width: 480px) {
table.mj-full-width-mobile {
width: 100% !important;
}
td.mj-full-width-mobile {
width: auto !important;
}
}
</style>
</head>
<body style="background-color: #8cead8">
<div style="background-color: #8cead8">
<!--[if mso | IE]>
<table
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
>
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 600px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #ffffff;
background-color: #ffffff;
width: 100%;
"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 20px 0;
padding-bottom: 20px;
padding-top: 20px;
text-align: center;
"
>
<!--[if mso | IE]>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td
class="" style="vertical-align:top;width:600px;"
>
<![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
>
<tr>
<td
align="center"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 10px;
padding-right: 0px;
padding-bottom: 10px;
padding-left: 0px;
word-break: break-word;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
border-collapse: collapse;
border-spacing: 0px;
"
>
<tbody>
<tr>
<td
style="
width: 250px;
"
>
<a
href="https://latienda.coop/"
target="_blank"
>
<img
alt=""
height="auto"
width="25"
align="left"
src="https://latienda.coop/_nuxt/img/latienda-logo.dea6549.png"
style="
border: none;
display: block;
outline: none;
text-decoration: none;
height: auto;
width: 100%;
font-size: 13px;
"
/>
</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<table
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
>
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 600px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #ffffff;
background-color: #ffffff;
width: 100%;
"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 20px 0;
padding-bottom: 0px;
padding-top: 0;
text-align: center;
"
>
<!--[if mso | IE]>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td
class="" style="vertical-align:top;width:600px;"
>
<![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
>
<tr>
<td
align="center"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 28px;
padding-right: 25px;
padding-bottom: 18px;
padding-left: 25px;
word-break: break-word;
"
>
<div
style="
font-family: Poppins,
Arial, sans-serif;
font-size: 20px;
font-weight: bold;
line-height: 1;
text-align: center;
color: #374493;
"
>
Sincronización realizada con éxito
</div>
</td>
</tr>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<table
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
>
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 600px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #ffffff;
background-color: #ffffff;
width: 100%;
"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 20px 0;
padding-bottom: 5px;
padding-top: 0;
text-align: center;
"
>
<!--[if mso | IE]>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td
class="" style="vertical-align:top;width:600px;"
>
<![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
>
<tr>
<td
align="center"
style="
font-size: 0px;
padding: 10px 25px;
padding-right: 0px;
padding-left: 0px;
word-break: break-word;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
border-collapse: collapse;
border-spacing: 0px;
"
>
<tbody>
<tr>
<td
style="
width: 250px;
"
></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr></tr>
<tr>
<td
align="center"
width="50"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 28px;
padding-right: 25px;
padding-bottom: 28px;
padding-left: 25px;
word-break: break-word;
"
>
<p
style="
font-family: Noto Sans,
sans-serif;
font-size: 17px;
line-height: 1.5;
text-align: center;
color: #374493;
margin: 0 50px;
"
>
Tu sincronización de productos desde tu tienda online ha finalizado con éxito.
<br>
<br>
Se han creado {{count}} productos nuevos.
<br>
<br>
</p>
</td>
</tr>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<table
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
>
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 600px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #ffffff;
background-color: #ffffff;
width: 100%;
"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 20px 0;
padding-bottom: 15px;
text-align: center;
"
>
<!--[if mso | IE]>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td
class="" style="vertical-align:top;width:300px;"
>
<![endif]-->
<div
class="mj-column-per-50 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
></table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<table
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
>
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<!--[if mso | IE]>
</td>
</tr>
</table>
<table
align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600"
>
<tr>
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
<![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 600px;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
>
<tr>
<td
align="center"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 20px;
padding-right: 25px;
padding-bottom: 20px;
padding-left: 25px;
word-break: break-word;
"
>
<div
style="
font-family: Poppins, Arial, sans-serif;
font-size: 15px;
line-height: 1;
text-align: center;
color: #374493;
"
>
2021 La Tienda.coop
</div>
</td>
</tr>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]>
</td>
</tr>
</table>
<![endif]-->
</div>
</body>
</html>

View File

@@ -65,15 +65,29 @@ def create_imported_product(info, company, history, user):
# alternative method
serializer = ProductSerializer(data=instance_data)
if serializer.is_valid():
try:
new = Product.objects.create(**serializer.validated_data)
# try:
# new = Product.objects.create(**serializer.validated_data)
# new.tags = tags
# new.attributes = attributes
# new.save()
# except Exception as e:
# logging.error(f"Could not create product instance: {str(e)}")
# return None
new, created = Product.objects.get_or_create(
company=company,
creator=user if user is not None else None,
history=history,
url=instance_data['url'],
stock=instance_data['stock'],
name=instance_data['name'],
description=instance_data['description'],
sku=instance_data['sku'],
price=instance_data['price']
)
new.tags = tags
new.attributes = attributes
new.save()
except Exception as e:
logging.error(f"Could not create product instance: {str(e)}")
return None
if len(info['images']) > 0:
try:
# get image
@@ -109,11 +123,13 @@ def migrate_shop_products(url, key, secret, user=None, version="wc/v3"):
# get wcapi
wcapi = get_wcapi_instance(url, key, secret, version)
consumer_key = 'ck_565539bb25b472b1ff7a209eb157ca11c0a26397'
consumer_secret = 'cs_9c1690ba5da0dd70f51d61c395628fa14d1a104c'
# get company fom url
company = Company.objects.filter(web_link=url).first()
company = Company.objects.filter(shop_link=url).first()
if not company:
logging.error(f"Could not find Company with URL: {url}")
@@ -122,8 +138,11 @@ def migrate_shop_products(url, key, secret, user=None, version="wc/v3"):
new_products = []
page = 1
attemps = 0
error = False
# list products
while True:
try:
response = wcapi.get('products/', params={'per_page': 10, 'page': page})
page += 1
@@ -131,14 +150,18 @@ def migrate_shop_products(url, key, secret, user=None, version="wc/v3"):
products = response.json()
elif response.status_code == 401:
logging.error(f"{response.status_code} [{response.url}]: {response.json()}")
return None
error = True
else:
logging.error(f"Could not load products from {response.url}: [{response.status_code}]")
print(f"Could not load products fom {response.url}: [{response.status_code}]")
return None
error = True
except requests.exceptions.ReadTimeout as e:
logging.error(f"Timeout reading backend: {str(e)}")
# skip and try next
attemps += 1
if attemps>4:
break
else:
continue
# exit loop if no more products
if not products:
@@ -149,7 +172,6 @@ def migrate_shop_products(url, key, secret, user=None, version="wc/v3"):
company=company,
sync_date=datetime.datetime.now(),
)
counter = 0
for product in products:
# check if exists
@@ -170,10 +192,11 @@ def migrate_shop_products(url, key, secret, user=None, version="wc/v3"):
history.quantity = counter
history.save()
logging.info(f"Products created: {len(new_products)}")
print(f"Products created: {len(new_products)}")
return new_products
return {"new_products": new_products, "error": error}