views.py 12.5 KB
Newer Older
Administrator committed
1 2 3 4 5
# coding: utf-8
"""Products main page."""
from outils.common_imports import *
from outils.for_view_imports import *

6
from members.models import CagetteUser
Administrator committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
from products.models import CagetteProduct
from products.models import CagetteProducts
from inventory.models import CagetteInventory
from shelfs.models import Shelfs

from outils.forms import GenericExportMonthForm
import os.path
import csv
from shutil import copyfile
from openpyxl import Workbook
from openpyxl.writer.excel import save_virtual_workbook
from datetime import date


def home(request):
    """Page de selection de produits pour récupérer des informations"""
    context = {
        'title': 'Produits'
    }
    template = loader.get_template('products/index.html')

    return HttpResponse(template.render(context, request))

30 31 32 33 34 35 36 37 38 39 40 41 42
def get_simple_list(request):
    res = {}
    try:
        res = CagetteProducts.get_simple_list()
    except Exception as e:
        coop_logger.error("Get products simple list : %s", str(e))
        res['error'] = str(e)
    if ('error' in res):
        return JsonResponse(res, status=500)
    else:
        return JsonResponse(res, safe=False)


43
def get_product_for_order_helper(request):
44 45
    res = {}
    try:
46 47 48 49
        data = json.loads(request.body.decode())
        pids = data['pids']
        stats_from = data['stats_from']
        res = CagetteProducts.get_products_for_order_helper(None, pids, stats_from)
50 51 52 53 54 55 56 57
    except Exception as e:
        coop_logger.error("get_product_for_help_order_line : %s", str(e))
        res['error'] = str(e)
    if ('error' in res):
        return JsonResponse(res, status=500)
    else:
        return JsonResponse(res, safe=False)

Administrator committed
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
def get_product_data(request):
    barcode = request.GET['barcode']
    res = CagetteProduct.get_product_from_barcode(barcode)

    if not res:
        return JsonResponse({"product": res}, status=404)

    p = res[0]
    if p['shelf_id'] is not False:
        shelfs_sortorder = Shelfs.get_shelfs_sortorder([p['shelf_id'][0]])

        try:
            p['shelf_sortorder'] = shelfs_sortorder[0]['sort_order']
        except Exception as e:
            p['shelf_sortorder'] = 'X'
73 74
    else:
        p['shelf_sortorder'] = 'X'
Administrator committed
75 76 77

    return JsonResponse({"product": p})

78 79 80 81 82 83 84 85 86 87
def get_products_stdprices(request):
    ids = json.loads(request.body.decode())
    res = CagetteProduct.get_products_stdprices(ids)

    if ('error' in res):
        return JsonResponse(res, status=500)
    else:
        return JsonResponse({"res": res})


Administrator committed
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
def update_product_stock(request):
    res = {}
    product_data = json.loads(request.body.decode())

    p = {
        'id': product_data['id'],
        'uom_id': product_data['uom_id'],
        'qty': product_data['qty']
    }

    inventory_data = {
        'name': product_data['name'] + ' - ' + date.today().strftime("%d/%m/%Y"),
        'products': [p]
    }

103
    res['inventory'] = CagetteInventory.update_products_stock(inventory_data)
Administrator committed
104 105 106

    return JsonResponse({"res": res})

Damien Moulard committed
107 108
def update_product_purchase_ok(request):
    res = {}
109 110 111
    is_connected_user = CagetteUser.are_credentials_ok(request)
    if is_connected_user is True:
        data = json.loads(request.body.decode())
Damien Moulard committed
112

113
        res = CagetteProduct.update_product_purchase_ok(data["product_tmpl_id"], data["purchase_ok"])
Damien Moulard committed
114

115 116 117 118
        if ('error' in res):
            return JsonResponse(res, status=500)
        else:
            return JsonResponse({"res": res})
Damien Moulard committed
119
    else:
120
        return JsonResponse(res, status=403)
Damien Moulard committed
121 122 123

def update_product_internal_ref(request):
    res = {}
124 125 126
    is_connected_user = CagetteUser.are_credentials_ok(request)
    if is_connected_user is True:
        data = json.loads(request.body.decode())
Damien Moulard committed
127

128
        res = CagetteProduct.update_product_internal_ref(data["product_tmpl_id"], data["default_code"])
Damien Moulard committed
129

130 131 132 133
        if ('error' in res):
            return JsonResponse(res, status=500)
        else:
            return JsonResponse({"res": res})
Damien Moulard committed
134
    else:
135 136
        return JsonResponse(res, status=403)

137
def commit_actions_on_product(request):
138 139 140 141 142
    res = {}
    is_connected_user = CagetteUser.are_credentials_ok(request)
    if is_connected_user is True:
        try:
            data = json.loads(request.body.decode())
143 144 145 146 147 148 149 150 151
            product_data = CagetteProducts.get_products_for_order_helper(None, [data["id"]])["products"][0]

            # Don't allow to archive product if incomin qty > 0
            if data["to_archive"] is True and product_data["incoming_qty"] > 0:
                res["code"] = "archiving_with_incoming_qty"
                return JsonResponse(res, status=500)
            
            res = CagetteProduct.commit_actions_on_product(data)

152 153
            do_stock_update = False
            # If product to archive and stock > 0: do inventory to set stock to 0
154
            if data["to_archive"] is True and product_data["qty_available"] != 0:
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
                p = { 
                    'id': product_data['product_variant_ids'][0],  # Need product id
                    'uom_id': product_data['uom_id'],
                    'qty': 0
                }

                inventory_data = {
                    'name': 'Archivage - ' + product_data['name'],
                    'products': [p]
                }

                do_stock_update = True

            # Else update actual stock if changed
            elif data["qty_available"] != product_data["qty_available"]:
                p = { 
                    'id': product_data['product_variant_ids'][0],  # Need product id
                    'uom_id': product_data['uom_id'],
                    'qty': data["qty_available"]
                }

                inventory_data = {
                    'name': 'MAJ stock depuis Aide à la Commande - ' + product_data['name'],
                    'products': [p]
                }

                do_stock_update = True

            if do_stock_update is True:
184
                try:
185
                    res_inventory = CagetteInventory.update_products_stock(inventory_data, 3)
186 187 188 189 190 191 192
                    if res_inventory['errors'] or res_inventory['missed']:
                        res["code"] = "error_stock_update"
                        res["error"] = res_inventory['errors']
                        return JsonResponse(res, status=500)
                except Exception as e:
                    res["code"] = "error_stock_update"
                    return JsonResponse(res, status=500)
193

194 195 196 197 198 199 200 201 202 203
        except Exception as e:
            res['error'] = str(e)
            coop_logger.error("Update npa and minimal stock : %s", res['error'])

        if ('error' in res):
            return JsonResponse(res, status=500)
        else:
            return JsonResponse({"res": res})
    else:
        return JsonResponse(res, status=403)
Administrator committed
204 205 206 207 208 209 210 211

def labels_appli_csv(request, params):
    """Generate files to put in DAV directory to be retrieved by scales app."""
    withCandidate = False
    res = {}
    try:
        if (params == '/wc'):
            withCandidate = True
212
        with_pos_categories = getattr(settings, 'EXPORT_POS_CAT_FOR_SCALES', False)
Administrator committed
213
        products = CagetteProducts.get_products_for_label_appli(withCandidate)
214 215 216 217 218
        if with_pos_categories is True:
            pos_categories = CagetteProducts.get_pos_categories()
        else:
            pos_categories = []

Administrator committed
219 220 221 222 223 224 225 226 227 228 229 230
        rows = []
        for p in products:
            if (p['sale_ok'] is True):
                if ('uom_id' in p):
                    uom = p['uom_id'][1]
                else:
                    uom = 'undefined'
                barcode = p['barcode']
                if (isinstance(barcode, bool)):
                    barcode = ''
                if not (barcode.isnumeric()):
                    barcode = ''
231 232 233 234 235 236 237 238 239 240 241
                p_row = [p['id'], p['display_name'], barcode,
                         p['list_price'],
                         p['categ'],
                         uom,
                         p['image'].replace("\n", "")]
                if with_pos_categories is True:
                    if p['pos_categ_id']:
                        p_row.append(p['pos_categ_id'][0])
                    else:
                        p_row.append('')
                rows.append(p_row)
Administrator committed
242 243 244 245 246

        header = ['id', 'nom', 'code-barre', 'prix',
                  'categorie', 'unite', 'image'
                  # 'en vente', 'sale_ok'
                  ]
247 248 249 250
        if with_pos_categories is True and len(pos_categories) > 0:
            header.append('id_categorie_pos')
            with open(settings.DAV_PATH + '/pos_categories.json', 'w') as outfile:
                json.dump(pos_categories, outfile)
Administrator committed
251 252 253 254

        os_file = settings.DAV_PATH + '/flv.csv'
        file_copies = []

255
        nb = int(getattr(settings, 'FLV_CSV_NB', 1))
Administrator committed
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270

        for i in range(1, nb + 1):
            file_copies.append(settings.DAV_PATH + '/flv_' + str(i) + '.csv')

        if os.path.exists(os_file):
            os.remove(os_file)
        file = open(os_file, 'w')
        writer_file = csv.writer(file, delimiter=';', quoting=csv.QUOTE_ALL)

        writer_file.writerow(header)
        for row in rows:
            writer_file.writerow(row)
        file.close()
        for c in file_copies:
            copyfile(os_file, c)
271 272


Administrator committed
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
    except Exception as e:
        res['error'] = str(e)
    return JsonResponse({'res': res})


def label_print(request, templ_id, price=None, ltype='shelf', nb=None):
    """Generate label formatted file for printing."""
    """
    Examples http://127.0.0.1:34001/products/label_print/6627/0.51/product/5
             http://127.0.0.1:34001/products/label_print/6627
    """

    directory = '/labels/'
    if ltype == 'product':
        directory = '/product_labels/'

    res = CagetteProduct.generate_label_for_printing(templ_id, directory, price, nb)

    return JsonResponse({'res': res})

def destocking(request):
	"""Page de selection de la commande suivant un fournisseurs"""
	context = {'title': 'Repas/pertes'}
	template = loader.get_template('products/destocking.html')
	return HttpResponse(template.render(context, request))

def get_all_available_products(request):
	return JsonResponse(CagetteProducts.get_all_available(), safe=False)

def get_all_barcodes(request):
    """Return all stored products barcodes."""
304 305
    import time
    start = int(round(time.time() * 1000))
Administrator committed
306 307
    res = {}
    try:
308 309 310 311 312 313 314 315
        res['list'] = CagetteProducts.get_all_barcodes()
        res['keys'] = {
            'name': 0,
            'sale_ok': 1,
            'purchase_ok': 2,
            'available_in_pos': 3,
            'id': 4,
            'standard_price': 5,
316 317
            'list_price': 6,
            'uom_id': 7
318
        }
Administrator committed
319
        rules = CagetteProducts.get_barcode_rules()
320 321 322

        res['patterns'] = rules['patterns']
        res['aliases'] = rules['aliases']
323
        res['time'] = int(round(time.time() * 1000)) - start
Administrator committed
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
    except Exception as e:
        coop_logger.error("products_barcodes : %s", str(e))
        res['error'] = str(e)
    return JsonResponse({'res': res})

def barcodes_check(request):
    bc_errors = CagetteProducts.find_bc_errors()
    wb = Workbook()
    ws1 = wb.create_sheet("Anomalies code-barres", 0)
    ws1.append(['Produits', 'code-barres', 'type d\'erreur'])
    for key, pdts in bc_errors.items():
        for p in pdts:
            ws1.append([p['display_name'], p['barcode'], key])
    wb_name = 'anomalie_code_barres.xlsx'
    response = HttpResponse(content=save_virtual_workbook(wb), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = 'attachment; filename=' + wb_name
    return response

def shelf_labels(request):
    result = {'done': False}
    try:
        products =  json.loads(request.POST.get('products'))
        directory = '/labels/'
        for p in products:
            templ_id = p['product_tmpl_id']
            price = nb = ''
            if 'price' in p:
                price = p['price']
            res = CagetteProduct.generate_label_for_printing(templ_id, directory, price, nb)
    except Exception as e:
        coop_logger.error("shelf_labels : %s", str(e))
        result['error'] = str(e)
    return JsonResponse(result)

def sales(request):
    if request.method == 'GET':
        template = loader.get_template('outils/data_export.html')
        context = {'form': GenericExportMonthForm(),
                   'title': 'Export ventes'}
        response = HttpResponse(template.render(context, request))
    else:
        res = CagetteProducts.get_sales(request)
        # return JsonResponse(res, safe=False)
        context = {'res': res,
                   'title': 'Ventes du mois ' + res['month']}
        template = loader.get_template('products/sales.html')
        response = HttpResponse(template.render(context, request))
    return response