From c19241dc3812c92b150376c3c8108c3359aaf488 Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Fri, 11 Dec 2015 11:42:51 +0200 Subject: Added upload prices function --- requirements.pip | 3 ++ servo/forms/product.py | 28 ++++++++------ servo/templates/products/index.html | 2 + servo/templates/products/upload_prices.html | 13 +++++++ servo/urls/products.py | 2 + servo/views/product.py | 58 ++++++++++++++++++++++++++++- settings.py | 3 ++ 7 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 servo/templates/products/upload_prices.html diff --git a/requirements.pip b/requirements.pip index 3cc6bf4..434b6a6 100644 --- a/requirements.pip +++ b/requirements.pip @@ -1,5 +1,6 @@ django==1.8.7 django-mptt +django-excel django-countries django-bootstrap3 djangorestframework @@ -17,6 +18,8 @@ celery chardet html2text python-magic +pyexcel-xls +pyexcel-xlsx -e git+git://github.com/filipp/py-gsxws.git#egg=gsxws --allow-external pil --allow-unverified pil diff --git a/servo/forms/product.py b/servo/forms/product.py index 61969f1..7e0f52e 100644 --- a/servo/forms/product.py +++ b/servo/forms/product.py @@ -12,14 +12,8 @@ from servo.forms.base import BaseModelForm, DatepickerInput, TextInput class ProductSearchForm(forms.Form): - title = forms.CharField( - required=False, - label=_('Name contains') - ) - code = forms.CharField( - required=False, - label=_('Code contains') - ) + title = forms.CharField(required=False, label=_('Name contains')) + code = forms.CharField(required=False, label=_('Code contains')) description = forms.CharField( required=False, label=_('Description contains') @@ -213,13 +207,23 @@ class ReserveProductForm(forms.Form): """ Form for reserving products for a given SO """ - inventory = forms.ModelChoiceField( - queryset=Inventory.objects.none(), - label=_('Inventory') - ) + inventory = forms.ModelChoiceField(queryset=Inventory.objects.none(), + label=_('Inventory')) def __init__(self, order, *args, **kwargs): super(ReserveProductForm, self).__init__(*args, **kwargs) inventory = Inventory.objects.filter(location=order.location, product__in=order.products.all()) self.fields['inventory'].queryset = inventory + + +class UploadPricesForm(forms.Form): + datafile = forms.FileField(label=_('Price data in Excel format (.xlsx)'), + help_text=_('This will also update products with fixed prices')) + create_new = forms.BooleanField(label=_('Create new products'), + required=False, + initial=True, + help_text=_('Create products if not found')) + set_fixed = forms.BooleanField(label=_('Set fixed price'), + required=False, + help_text=_('Mark all uploaded products as having a fixed price')) diff --git a/servo/templates/products/index.html b/servo/templates/products/index.html index 24c4d5f..4b83383 100755 --- a/servo/templates/products/index.html +++ b/servo/templates/products/index.html @@ -36,6 +36,8 @@
  • {% trans "Download Products" %}
  • {% trans "Download Inventory Report" %}
  • +
  • +
  • {% trans "Upload Prices" %}
  • {% trans "Upload Products" %}
  • {% trans "Upload Parts Database" %}
  • diff --git a/servo/templates/products/upload_prices.html b/servo/templates/products/upload_prices.html new file mode 100644 index 0000000..746842b --- /dev/null +++ b/servo/templates/products/upload_prices.html @@ -0,0 +1,13 @@ +{% extends "modal.html" %} +{% load i18n %} + +{% block header %} + {{ title }} +{% endblock header %} + +{% block body %} +
    + {% csrf_token %} + {% include "form_snippet.html" %} +
    +{% endblock body %} diff --git a/servo/urls/products.py b/servo/urls/products.py index 6d54ff1..3004d40 100644 --- a/servo/urls/products.py +++ b/servo/urls/products.py @@ -17,6 +17,8 @@ urlpatterns = patterns( name="products-upload_products"), url(r'^upload/parts/$', "upload_gsx_parts", name="products-upload_gsx_parts"), + url(r'^upload/prices/$', "upload_prices", + name="products-upload_prices"), url(r'^update_price/(\d+)/$', "update_price", name="products-update_price"), diff --git a/servo/views/product.py b/servo/views/product.py index 1ff344e..4c7f96f 100644 --- a/servo/views/product.py +++ b/servo/views/product.py @@ -19,7 +19,8 @@ from servo.models import (Attachment, TaggedItem, Product, ProductCategory, Inventory, Location, inventory_totals, GsxAccount,) -from servo.forms.product import ProductForm, CategoryForm, ProductSearchForm +from servo.forms.product import (ProductForm, CategoryForm, ProductSearchForm, + UploadPricesForm,) def prep_list_view(request, group='all'): @@ -481,6 +482,9 @@ def get_info(request, location, code): def update_price(request, pk): + """ + Updates the price info from GSX + """ product = get_object_or_404(Product, pk=pk) try: GsxAccount.default(request.user) @@ -490,3 +494,55 @@ def update_price(request, pk): messages.error(request, _('Failed to update price from GSX')) return redirect(product) + + +def upload_prices(request): + """ + Uploads new price data from Excel file + """ + form = UploadPricesForm() + action = request.path + title = _('Upload new price data') + + if request.method == 'POST': + form = UploadPricesForm(request.POST, request.FILES) + + if form.is_valid(): + import django_excel as excel + import pyexcel.ext.xls # import it to handle xls file + import pyexcel.ext.xlsx # import it to handle xlsx file + + counter, errors = 0, 0 + datafile = form.cleaned_data['datafile'] + sheet = datafile.get_sheet() + del(sheet.row[0]) # skip header row + + for row in sheet: + if not len(row[0]): + continue # skip empty rows + + try: + product = Product.objects.get(code=row[0]) + except Product.DoesNotExist: + if form.cleaned_data.get('create_new'): + product = Product(code=row[0]) + else: + error = _('Error on row %d - product %s not found') % (counter+1, row[0]) + messages.error(request, error) + return redirect(list_products) + + product.title = row[1] + product.description = row[2] + product.price_sales_exchange = row[3] + + if form.cleaned_data.get('set_fixed'): + product.fixed_price = True + + product.save() + counter += 1 + + msg = _('Price info of %d products uploaded successfully') % counter + messages.success(request, msg) + return redirect(list_products) + + return render(request, "products/upload_prices.html", locals()) diff --git a/settings.py b/settings.py index f62b448..3734deb 100644 --- a/settings.py +++ b/settings.py @@ -158,6 +158,9 @@ LOGGING = { } } +FILE_UPLOAD_HANDLERS = ("django_excel.ExcelMemoryFileUploadHandler", + "django_excel.TemporaryExcelFileUploadHandler",) + SESSION_ENGINE = "django.contrib.sessions.backends.cached_db" TEMPLATE_CONTEXT_PROCESSORS = ( -- cgit v1.2.3