Added GTIN product storage and remote service integration
This commit is contained in:
		@@ -1,5 +1,6 @@
 | 
				
			|||||||
from django.contrib import admin
 | 
					from django.contrib import admin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import Asset
 | 
					from .models import Asset, GtinProduct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
admin.site.register(Asset)
 | 
					admin.site.register(Asset)
 | 
				
			||||||
 | 
					admin.site.register(GtinProduct)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								asset/forms.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								asset/forms.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					from django import forms
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AssetForm(forms.Form):
 | 
				
			||||||
 | 
					    named_id = forms.CharField(label='Asset named ID', max_length=30)
 | 
				
			||||||
 | 
					    description = forms.CharField(label='Description', max_length=250)
 | 
				
			||||||
 | 
					    color = forms.CharField(label='Color', max_length=20)
 | 
				
			||||||
 | 
					    container_type = forms.ChoiceField(label='Container Type', )
 | 
				
			||||||
							
								
								
									
										41
									
								
								asset/gtin_service.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								asset/gtin_service.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					from .models import GtinProduct
 | 
				
			||||||
 | 
					from django.db.models import ObjectDoesNotExist
 | 
				
			||||||
 | 
					import requests
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def ask_upcitemdb_service(gtin):
 | 
				
			||||||
 | 
					    request = f'https://api.upcitemdb.com/prod/trial/lookup?upc={gtin}'
 | 
				
			||||||
 | 
					    response = requests.get(request)
 | 
				
			||||||
 | 
					    if response.status_code == 200:
 | 
				
			||||||
 | 
					        productJson = response.json()
 | 
				
			||||||
 | 
					        print(f"Got {productJson['total']} result records")
 | 
				
			||||||
 | 
					        if productJson['total'] > 0:
 | 
				
			||||||
 | 
					            product = GtinProduct.objects.create(gtin=gtin, api_request=request, api_response=productJson)
 | 
				
			||||||
 | 
					            if 'title' in productJson['items'][0]:
 | 
				
			||||||
 | 
					                product.name = productJson['items'][0]['title']
 | 
				
			||||||
 | 
					            if 'brand' in productJson['items'][0]:
 | 
				
			||||||
 | 
					                product.brand = productJson['items'][0]['brand']
 | 
				
			||||||
 | 
					            LOGGER.debug(
 | 
				
			||||||
 | 
					                f"Creating new product entry for gtin={gtin}:\nrequest={request}\nresponse={response.status_code}:{productJson}")
 | 
				
			||||||
 | 
					            product.save()
 | 
				
			||||||
 | 
					            return product
 | 
				
			||||||
 | 
					    return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def ask_remote_services(gtin):
 | 
				
			||||||
 | 
					    product = ask_upcitemdb_service(gtin)
 | 
				
			||||||
 | 
					    if product is not None:
 | 
				
			||||||
 | 
					        return product
 | 
				
			||||||
 | 
					    return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_by_gtin(gtin):
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        product = GtinProduct.objects.get(gtin=gtin)
 | 
				
			||||||
 | 
					    except ObjectDoesNotExist:
 | 
				
			||||||
 | 
					        # ask remote services
 | 
				
			||||||
 | 
					        product = ask_remote_services(gtin)
 | 
				
			||||||
 | 
					    return product
 | 
				
			||||||
							
								
								
									
										26
									
								
								asset/migrations/0003_gtinproduct.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								asset/migrations/0003_gtinproduct.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					# Generated by Django 4.0.3 on 2022-04-13 12:08
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('asset', '0002_auto_20220310_1620'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.CreateModel(
 | 
				
			||||||
 | 
					            name='GtinProduct',
 | 
				
			||||||
 | 
					            fields=[
 | 
				
			||||||
 | 
					                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
				
			||||||
 | 
					                ('gtin', models.CharField(max_length=40, unique=True)),
 | 
				
			||||||
 | 
					                ('api_request', models.CharField(max_length=250)),
 | 
				
			||||||
 | 
					                ('api_response', models.CharField(max_length=4096)),
 | 
				
			||||||
 | 
					                ('name', models.CharField(blank=True, max_length=200)),
 | 
				
			||||||
 | 
					                ('brand', models.CharField(blank=True, max_length=40)),
 | 
				
			||||||
 | 
					                ('created_ts', models.DateTimeField(auto_now_add=True, verbose_name='datetime created')),
 | 
				
			||||||
 | 
					                ('changed_ts', models.DateTimeField(auto_now=True, verbose_name='datetime updated')),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -23,3 +23,13 @@ class Asset(models.Model):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def get_absolute_url(self):
 | 
					    def get_absolute_url(self):
 | 
				
			||||||
        return reverse('asset:detail', kwargs={'pk': self.pk})
 | 
					        return reverse('asset:detail', kwargs={'pk': self.pk})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GtinProduct(models.Model):
 | 
				
			||||||
 | 
					    gtin = models.CharField(max_length=40, unique=True)
 | 
				
			||||||
 | 
					    api_request = models.CharField(max_length=250)
 | 
				
			||||||
 | 
					    api_response = models.CharField(max_length=4096)
 | 
				
			||||||
 | 
					    name = models.CharField(max_length=200, blank=True)
 | 
				
			||||||
 | 
					    brand = models.CharField(max_length=40, blank=True)
 | 
				
			||||||
 | 
					    created_ts = models.DateTimeField('datetime created', auto_now_add=True)
 | 
				
			||||||
 | 
					    changed_ts = models.DateTimeField('datetime updated', auto_now=True)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,10 +49,23 @@
 | 
				
			|||||||
  <!-- Action buttons -->
 | 
					  <!-- Action buttons -->
 | 
				
			||||||
  <div class="row">
 | 
					  <div class="row">
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
    <div class="col-sm-12">
 | 
					    <form method="post" action="{% url 'asset:add-by-gtin' %}">
 | 
				
			||||||
      <a class="btn btn-primary" href="{% url 'asset:add' %}" role="button">+ Asset</a>
 | 
					        {% csrf_token %}
 | 
				
			||||||
      <a class="btn btn-primary" href="{% url 'container:add' %}" role="button">+ Container</a>
 | 
					        <div class="col-sm-12">
 | 
				
			||||||
    </div>
 | 
					            <div class="col-4">
 | 
				
			||||||
 | 
					              <a class="btn btn-primary" href="{% url 'asset:add' %}" role="button">+ Asset</a>
 | 
				
			||||||
 | 
					              <a class="btn btn-primary" href="{% url 'container:add' %}" role="button">+ Container</a>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="col-4">
 | 
				
			||||||
 | 
					                <div class="input-group">
 | 
				
			||||||
 | 
					                    <input type="text" class="form-control" name="gtin" placeholder="EAN, UPC or GTIN" maxlength="20">
 | 
				
			||||||
 | 
					                    <div class="input-group-append">
 | 
				
			||||||
 | 
					                        <button class="btn btn-primary" type="submit" id="assetFromGtin">+Asset from GTIN</button>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <!-- End Action buttons -->
 | 
					  <!-- End Action buttons -->
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,12 @@
 | 
				
			|||||||
from django.urls import path
 | 
					from django.urls import path
 | 
				
			||||||
from . import views
 | 
					from . import views
 | 
				
			||||||
from asset.views import AssetCreateView, AssetDeleteView, AssetUpdateView, AssetListView
 | 
					from asset.views import AssetCreateView, AssetDeleteView, AssetUpdateView, AssetListView, asset_from_gtin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app_name = 'asset'
 | 
					app_name = 'asset'
 | 
				
			||||||
urlpatterns = [
 | 
					urlpatterns = [
 | 
				
			||||||
    path('', AssetListView.as_view(), name='list'),
 | 
					    path('', AssetListView.as_view(), name='list'),
 | 
				
			||||||
    path('add/', AssetCreateView.as_view(), name='add'),
 | 
					    path('add/', AssetCreateView.as_view(), name='add'),
 | 
				
			||||||
 | 
					    path('addbygtin/', asset_from_gtin, name='add-by-gtin'),
 | 
				
			||||||
    path('<int:pk>/', AssetUpdateView.as_view(), name='update'),
 | 
					    path('<int:pk>/', AssetUpdateView.as_view(), name='update'),
 | 
				
			||||||
    path('<int:pk>/', AssetUpdateView.as_view(), name='detail'),
 | 
					    path('<int:pk>/', AssetUpdateView.as_view(), name='detail'),
 | 
				
			||||||
    path('<int:pk>/delete/', AssetDeleteView.as_view(), name='delete'),
 | 
					    path('<int:pk>/delete/', AssetDeleteView.as_view(), name='delete'),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,3 +54,15 @@ def asset_save(request, asset_id):
 | 
				
			|||||||
    asset.quantity = request.POST['quantity']
 | 
					    asset.quantity = request.POST['quantity']
 | 
				
			||||||
    asset.save();
 | 
					    asset.save();
 | 
				
			||||||
    return HttpResponseRedirect(reverse('asset:list'))
 | 
					    return HttpResponseRedirect(reverse('asset:list'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def asset_from_gtin(request):
 | 
				
			||||||
 | 
					    from .gtin_service import get_by_gtin
 | 
				
			||||||
 | 
					    gtin = request.POST['gtin']
 | 
				
			||||||
 | 
					    print(f'Try gtin={gtin}')
 | 
				
			||||||
 | 
					    product = get_by_gtin(gtin)
 | 
				
			||||||
 | 
					    if product is None:
 | 
				
			||||||
 | 
					        print(f'ERROR: Could not create asset for gtin={gtin}')
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        print(f'Create new product: {product.name}, brand={product.brand}, gtin={product.gtin}')
 | 
				
			||||||
 | 
					    return HttpResponseRedirect(reverse('asset:list'))
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user