"""
informant_erp/ajax.py
Author: Haidar Khazen
Created 7/3/20

AJAX Functions for Informant ERP

"""
import json
from datetime import date
from decimal import Decimal
from django.apps import apps
from django.http import JsonResponse, HttpResponse
from django.db.models import F, Sum
from django.template.loader import render_to_string
from django.contrib import messages
from informant_site.utils import get_global_setting
from support.utilities import get_date
from support.decorators import deny_get
from informant_lookups.models import Item, CarLocSite, LineFeedSystem, FdrSpecial
from .utils import new_ncmtrx, DecimalEncoder
from .models import InvLog, JobLog, InvLoc, InvTrx, InvMin, ShipLog, ShipTrx, CarLoc, ProLog, ProDetail, NCMLog, FrmLog, FrmItem, FrmDevRw, FdrExperience, FdrLog, RunLog

# Autofill certain fields from item selected in lookup
@deny_get
def fill_invlog_info(request):
    item_id = request.POST.get('item_id', None)
    try:    #If item does not exist based un user typing, do nothing, keep value user typed.  Will crash upon saving - solution - create new item with other field values from here, or do not allow editing
        item = Item.objects.get(id=item_id)
        data = {'cust_item_code': item.cust_item_code,
                'package_id':item.package_id,
                'description': item.description,
                'customer_id': item.customer_id,
                'unit_weight': item.unit_weight,
                'inv_class_id': item.inv_class_id,
                'inv_group_id': item.inv_group_id}
    except:
        data = {'error': 'Item does not exist'}
    return JsonResponse(data)

# Autofill certain fields from joblog selected in job product
@deny_get
def fill_joblog_info(request):
    item_id = request.POST.get('id', None)
    try:    #If item does not exist based un user typing, do nothing, keep value user typed.  Will crash upon saving - solution - create new item with other field values from here, or do not allow editing
        item = Item.objects.get(id=item_id)
        data = {'product': item.name,
                'customer': item.customer_id,}  # Returns product name and customer - ver must be filled by user 
    except:
        data = {'error': 'Item does not exist'}
    return JsonResponse(data)

# Autofill certain fields from frmlog selected in job product
@deny_get
def fill_job_frmlog_info(request):
    frmlog_id = request.POST.get('id', None)
    try:    #If item does not exist based un user typing, do nothing, keep value user typed.  Will crash upon saving - solution - create new item with other field values from here, or do not allow editing
        frmlog = FrmLog.objects.get(id=frmlog_id)
        data = {'product': frmlog.product.name,
                'customer': frmlog.customer_id,
                'ver':frmlog.frm_ver}
    except:
        data = {'error': 'Frmlog does not exist'}
    return JsonResponse(data)

# Autofill certain fields from frmlog selected in job product
@deny_get
def fill_frmlog_info(request):
    frmlog_id = request.POST.get('id', None)
    try:    #If item does not exist based un user typing, do nothing, keep value user typed.  Will crash upon saving - solution - create new item with other field values from here, or do not allow editing
        frmlog = FrmLog.objects.get(id=frmlog_id)
        data = {'product_id': frmlog.product.id,
                'product': frmlog.product.name,
                'customer': frmlog.customer_id,
                'ver':frmlog.frm_ver}
    except:
        data = {'error': 'Frmlog does not exist'}
    return JsonResponse(data)

# Autofill feeder info if item selected matches characteristics in FdrExperience
@deny_get
def fill_feeder_info(request):
    item_id = request.POST.get('id', None)
    fdr_specials = FdrSpecial.objects.all()
    fdr_name_list = fdr_specials.values_list('name', flat=True)
    if item_id not in fdr_name_list: 
        item_characteristic = Item.objects.get(id=item_id).characteristic
    else:
        item_characteristic = fdr_specials.get(name=item_id).characteristic
    feeder = request.POST.get('feeder', None)
    line = request.POST.get('line', None)
    if item_characteristic is not None:
        try:    #If item does not exist based un user typing, do nothing, keep value user typed.  Will crash upon saving - solution - create new item with other field values from here, or do not allow editing
            experience = FdrExperience.objects.filter(characteristic=item_characteristic, feeder_id=feeder, line_id=line).first()
            data = {'feeder_type': experience.feeder_type_id,
                    'agitator': experience.agitator,
                    'tube_screw': experience.tube_screw_id,
                    'switch': experience.switch_id,
                    'refill': experience.refill,
                    'iff': experience.iff}
        except:
            data = {'error': 'Experience does not exist'}
    else:
        data = {'error': 'Item has no characteristic'}
    return JsonResponse(data)

# If reference exists in joblog table, return true
#   And calculate amount previously consumed
@deny_get
def check_reference(request):
    reference_id = request.POST.get('reference_id', None)
    receiver_id = request.POST.get('receiver_id', None)
    if reference_id is not None:
        try:
            job = JobLog.objects.exclude(status_id='CAN').get(job=reference_id)    #Do not allow canceled jobs       
            #  Calculate amount previously consumed
            prev_consumed = 0
            txns =InvTrx.objects.filter(receiver_id=receiver_id, reference=reference_id) 
            for txn in txns:
                if txn.consumed is not None:  # don't use transactions that were not a consume transaction
                    prev_consumed += Decimal(txn.consumed)
            data = {'reference_is_job': True,
                    'amt_prev_consumed': int(prev_consumed),
                    'job_status': job.status_id,
                    }
        except:
            data = {'reference_is_job': 'No Access'}
    else:
        data = {'reference_is_job': False}
    return JsonResponse(data)

# Generic autocomplete
# Uses extra parameters to retrieve the right info
def select_autocomplete(request):
    if request.is_ajax():
        term = request.GET.get('term', None)
        app = request.GET.get('app', None)
        model_class = request.GET.get('model_class', None)
        search_field = request.GET.get('search_field', None)
        order_field = request.GET.get('order_field', None)
        target_field = request.GET.get('target_field', None)
        label_field = request.GET.get('label_field', None)
        filter_on = request.GET.get('filter_on', None)
        filter_value = request.GET.get('filter_value', None)
        filter_lookup = request.GET.get('filter_lookup', None)
        distinct = request.GET.get('distinct', None)
        if app == 'undefined':
            app = 'informat_erp'
        if model_class == 'undefined':
            model_class = 'InvLog'
        if search_field == 'undefined':
            search_field = 'receiver'
        if order_field == 'undefined':
            order_field = 'receiver'
        if target_field == 'undefined':
            target_field = 'slug'
        if label_field == 'undefined':
            label_field = 'receiver'
        TargetModel = apps.get_model(app, model_class)
        if term:
            records = TargetModel.objects.filter(**{f'{search_field}__istartswith': term}).order_by(order_field)
        else:
            records = TargetModel.objects.all().order_by(order_field)
        if filter_on != 'undefined' and filter_on is not None:
            if filter_lookup == 'undefined':
                filter_lookup = 'gt'
            records = records.filter(**{f'{filter_on}__{filter_lookup}': Decimal(filter_value)})  # DANGER: right now, only filter is Decimal.  A string will break this.  If a string or date filter is needed, will need to add additiona logic to test for numeric/float
        if distinct != '' and distinct != 'undefined' and distinct is not None:
            records = records.distinct(distinct)
        results=[]
        for record in records:
            record_json = {}
            record_json['id'] = getattr(record, target_field)  #since we have the slug, better to use it for id
            record_json['label'] = getattr(record, label_field)
            record_json['value'] = getattr(record, label_field) #Use label_field (PK) instead of target_field(slug) since this displayed in dropdown
            results.append(record_json)
    else:
        results = 'fail'
    data = json.dumps(results)
    mimetype = 'application/json'
    return HttpResponse(data, mimetype)


# Search logic for each autocomplete field
def receiver_autocomplete(request):
    if request.is_ajax():
        term = request.GET.get("term")
        qty_filter = request.GET.get('qty_filter', None)
        if term:
            inv_logs = InvLog.objects.filter(receiver__istartswith=term).order_by('receiver')
        else:
            inv_logs = InvLog.objects.all().order_by('receiver')
        if qty_filter != 'undefined' and qty_filter is not None:
            inv_logs = inv_logs.filter(qty_on_hand__gt=Decimal(qty_filter))
        results=[]
        for inv_log in inv_logs:
            inv_log_json = {}
            inv_log_json['id'] = inv_log.slug   #since we have the slug, better to use it for id
            inv_log_json['label'] = inv_log.receiver
            inv_log_json['value'] = inv_log.slug    #since using for redirects, value should be the unique slug
            results.append(inv_log_json)
    else:
        results='fail'
    data = json.dumps(results)
    mimetype = 'application/json'
    return HttpResponse(data, mimetype)

# Search logic for each autocomplete fields
def release_autocomplete(request):
    if request.is_ajax():
        term = request.GET.get("term")
        if term:
            ship_logs = ShipLog.objects.filter(release__istartswith=term).order_by('release')
        else:
            ship_logs = ShipLog.objects.all().order_by('release')
        results=[]
        for ship_log in ship_logs:
            ship_log_json = {}
            ship_log_json['id'] = ship_log.slug   #since we have the slug, better to use it for id
            ship_log_json['label'] = ship_log.release
            ship_log_json['value'] = ship_log.slug    #since using for redirects, value should be the unique slug
            results.append(ship_log_json)
    else:
        results='fail'
    data = json.dumps(results)
    mimetype = 'application/json'
    return HttpResponse(data, mimetype)

# Search logic for each autocomplete field
def job_autocomplete(request):
    if request.is_ajax():
        term = request.GET.get("term")
        if term:
            job_logs = JobLog.objects.filter(job__istartswith=term).order_by('job')
        else:
            job_logs = JobLog.objects.all().order_by('job')
        results=[]
        for job_log in job_logs:
            job_log_json = {}
            job_log_json['id'] = job_log.slug   #since we have the slug, better to use it for id
            job_log_json['label'] = job_log.job
            job_log_json['value'] = job_log.slug    #since using for redirects, value should be the unique slug
            results.append(job_log_json)
    else:
        results='fail'
    data = json.dumps(results)
    mimetype = 'application/json'
    return HttpResponse(data, mimetype)

# Delete any locations associated with incoming receiver
@deny_get
def purge_locations(request):
    receiver_slug = request.POST.get('receiver_slug', None)
    if receiver_slug is not None:
        try:
            InvLoc.objects.filter(receiver__slug=receiver_slug).delete()
            messages.success(request, "Locations successfully purged.")
            data = {'success': 'Locations successfully purged.'}
        except:
            data = {'error': 'Something went wrong'}
    else:
        data = {'error': 'No slug received'}
    return JsonResponse(data)

@deny_get
def ship_order_info(request):
    reference_id = request.POST.get('reference_id', None)
    if reference_id is not None:
        try:
            ship_info = ShipTrx.objects.filter(release_id=reference_id)   
            html = render_to_string('informant_erp/fragments/ship_order_info.html', {'ship_info': ship_info})
            return HttpResponse(html)
        except:
            data = {'error': 'An error occurred'}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

@deny_get
def job_info(request):
    reference_id = request.POST.get('reference_id', None)
    if reference_id is not None:
        try:
            job_info = JobLog.objects.filter(job=reference_id)   
            html = render_to_string('informant_erp/fragments/job_info.html', {'job_info': job_info})
            return HttpResponse(html)
        except:
            data = {'error': 'An error occurred'}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

# Job info fragment for Pronew/prorevise
@deny_get
def pro_job_info(request):
    reference_id = request.POST.get('reference_id', None)
    if reference_id is not None:
        try:
            job_info = JobLog.objects.get(job=reference_id)   
            html = render_to_string('informant_erp/fragments/pro_job_info.html', {'job_info': job_info})
            return HttpResponse(html)
        except:
            data = {'error': 'An error occurred'}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

# Related prolog data fragment for Pronew/prorevise
@deny_get
def prolog_data(request):
    shift = request.POST.get('shift', None)
    team = request.POST.get('team', None)
    pro_date = get_date(request.GET.get('date',''))
    '''
    try:  # 4 digit year
        date = datetime.strptime(request.POST.get('date', None), "%m/%d/%Y").date()
    except:  #2 digit year
        date = datetime.strptime(request.POST.get('date', None), "%m/%d/%y").date()
    '''
    try:
        prologs = ProLog.objects.filter(shift=shift).filter(team=team).filter(date=pro_date).order_by('line')   
        html = render_to_string('informant_erp/fragments/prolog_data.html', {'prologs': prologs})
        return HttpResponse(html)
    except:
        data = {'error': 'An error occurred'}
    return JsonResponse(data)

@deny_get
def prolog_ncm_block(request):
    reference_id = request.POST.get('reference_id', None)
    try:
        ncmlog_records = NCMLog.objects.filter(reference=reference_id).order_by('disposition', 'ncm')  
        html = render_to_string('informant_erp/fragments/pro_ncmlog_block.html', {'ncmlog_records': ncmlog_records})
        return HttpResponse(html)
    except:
        data = {'error': 'An error occurred'}
    return JsonResponse(data)
    """
    if reference_id is not None and reference_id != "":
        try:
            ncmlog_records = NCMLog.objects.filter(reference=reference_id)   
            html = render_to_string('informant_erp/fragments/pro_ncmlog_block.html', {'ncmlog_records': ncmlog_records})
            return HttpResponse(html)
        except:
            data = {'error': 'An error occurred'}
    else:
        ncmlog_records = NCMLog.objects.filter(reference=reference_id)   
        html = render_to_string('informant_erp/fragments/pro_ncmlog_block.html', {'ncmlog_records': ncmlog_records})
        return HttpResponse(html)
    
    
    """

# Part of submit validation on ship order page
@deny_get
def check_item_in_releases(request):
    item = request.POST.get('item_id', None)
    release = request.POST.get('release_id', None)
    lot = request.POST.get('lot', None)
    if item is not None and release is not None and lot is not None:
        try:
            item_match = False
            lot_match = False
            ship_transactions = ShipTrx.objects.filter(release_id=release, item_id=item)
            if ship_transactions.exists():
                item_match = True
            for txn in ship_transactions:
                if txn.lot == lot and txn.item_id == item:
                    lot_match = True
            data = {'item_match': item_match,
                    'lot_match': lot_match}
        except:
            data = {'error': 'An error occurred'}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

# Inventory Transfer logic
# Get HTML block and remarks for the receiver but in two separate calls - if called for HTML, return HTML, if called for remarks, return JSON
# Calling function should specify return type
# From info
@deny_get
def get_receiver_from_info(request):
    return_type = request.POST.get('return_type', None)
    receiver_id = request.POST.get('receiver_id', None)
    new_receiver_id = request.POST.get('new_receiver_id', None)
    if receiver_id is not None:
        try:
            receiver_info = InvLog.objects.get(receiver=receiver_id)
            if receiver_info.qty_on_hand <= 0 or receiver_info.qty_on_hand is None:
                data = {'error': 'Error: Qty 0'}
            else:
                if new_receiver_id is None:
                    qty_data_id = f"id_qty_{receiver_id}"
                    item_data_id = f"id_item_{receiver_id}"
                else:
                    qty_data_id = f"id_qty_{new_receiver_id}"
                    item_data_id = f"id_item_{new_receiver_id}"
                if return_type == 'html':
                    return HttpResponse(render_to_string('informant_erp/fragments/inv_transfer_receiver_info.html', {'receiver_info': receiver_info, 'qty_data_id': qty_data_id, 'item_data_id': item_data_id}))
                else:
                    data = {'remarks': receiver_info.remarks,
                            'item_from': receiver_info.item.name,
                            'item_id': receiver_info.item.id}
        except:
            data = {'error': 'Receiver does not exist'}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

# To Info
@deny_get
def get_receiver_to_info(request):
    return_type = request.POST.get('return_type', None)
    receiver_id = request.POST.get('receiver_id', None)
    item_from = request.POST.get('item_from', None)
    if receiver_id is not None and item_from is not None:
        try:
            receiver_to_info = InvLog.objects.get(receiver=receiver_id)
            if receiver_to_info.item.name == item_from:  #If items match, proceed
                qty_data_id = f"id_qty_{receiver_id}"
                item_data_id = f"id_item_{receiver_id}"
                if return_type == 'html':
                    return HttpResponse(render_to_string('informant_erp/fragments/inv_transfer_receiver_info.html', {'receiver_info': receiver_to_info, 'qty_data_id': qty_data_id, 'item_data_id': item_data_id}))
                else:
                    data = {'remarks': receiver_to_info.remarks}
            else:
                data = {'error': 'Item mismatch'}                
        except:
            data = {'error': 'Receiver does not exist'}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

# If To: does not exist and user requests new reocrd, create
@deny_get
def create_new_to(request):
    #add concurrency qty check - qty to trasnfer needs to be sent in and compared to qty on hand of from - return error if not enough
    copy_from_receiver_id = request.POST.get('copy_from_receiver_id', None)
    new_receiver_id = request.POST.get('new_receiver_id', None)
    transfer_qty = request.POST.get('transfer_qty', None)
    try:
        new_receiver_info = InvLog.objects.get(receiver=copy_from_receiver_id)
        transfer_qty_dec = Decimal(transfer_qty.replace(',',''))
        if new_receiver_info.qty_on_hand < transfer_qty_dec:  # Concurrency - if not enough, return error
            data = {'error': 'Qty on hand too low'}
        else:
            new_receiver_info.receiver = new_receiver_id
            new_receiver_info.qty_on_hand = 0
            new_receiver_info.remarks = ""
            new_receiver_info.disp_remarks = ""
            new_receiver_info.save()
            # Add new invtrx with received = 0
            new_invtrx = InvTrx()
            new_invtrx.receiver_id = new_receiver_id
            new_invtrx.reference = f"MT-{new_receiver_id}"
            new_invtrx.transaction_date = date.today()
            new_invtrx.days = 0
            new_invtrx.received = 0
            new_invtrx.trans_qty = 0
            new_invtrx.user = request.user
            new_invtrx.save()
            data = {'success': 'Created new to record'}
    except:
        data = {'error': 'An error has occurred'}
    return JsonResponse(data)

# Inventory Reclass logic
# Get HTML block and remarks for the receiver but in two separate calls - if called for HTML, return HTML, if called for remarks, return JSON
# Calling function should specify return type
# From info
@deny_get
def get_reclass_receiver_from_info(request):
    return_type = request.POST.get('return_type', None)
    receiver_id = request.POST.get('receiver_id', None)
    if receiver_id is not None:
        try:
            receiver_info = InvLog.objects.get(receiver=receiver_id)
            if receiver_info.qty_on_hand <= 0 or receiver_info.qty_on_hand is None:
                data = {'error': 'Error: Qty 0'}
            else:
                qty_data_id = f"id_qty_{receiver_id}"
                item_data_id = f"id_item_{receiver_id}"
                cust_item_code_data_id = f"id_cust_item_code_{receiver_id}"
                lot_data_id = f"id_lot_{receiver_id}"
                if return_type == 'html':
                    return HttpResponse(render_to_string('informant_erp/fragments/inv_reclass_receiver_info.html', {'receiver_info': receiver_info, 'qty_data_id': qty_data_id, 'item_data_id': item_data_id, 'cust_item_code_data_id': cust_item_code_data_id, 'lot_data_id': lot_data_id}))
                else:
                    data = {'remarks': receiver_info.remarks,
                            'item_from': receiver_info.item.name,
                            'cust_item_code_from': receiver_info.item.cust_item_code
                            }
        except:
            data = {'error': 'Receiver does not exist'}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

@deny_get
def get_reclass_receiver_to_info(request):
    return_type = request.POST.get('return_type', None)
    receiver_id = request.POST.get('receiver_id', None)
    if receiver_id is not None:
        try:
            receiver_info = InvLog.objects.get(receiver=receiver_id)
            qty_data_id = f"id_qty_{receiver_id}"
            item_data_id = f"id_item_{receiver_id}"
            cust_item_code_data_id = f"id_cust_item_code_{receiver_id}"
            lot_data_id = f"id_lot_{receiver_id}"
            if return_type == 'html':
                return HttpResponse(render_to_string('informant_erp/fragments/inv_reclass_receiver_info.html', {'receiver_info': receiver_info, 'qty_data_id': qty_data_id, 'item_data_id': item_data_id, 'cust_item_code_data_id': cust_item_code_data_id, 'lot_data_id': lot_data_id}))
            else:
                data = {'remarks': receiver_info.remarks,
                        'item_from': receiver_info.item.name,
                        'cust_item_code_from': receiver_info.item.cust_item_code
                        }
        except:
            data = {'error': 'Receiver does not exist'}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

@deny_get
def get_cust_item_code(request):
    item_id = request.POST.get('item_id', None)
    if item_id is not None and item_id != '':
        try:
            item = Item.objects.get(id=item_id)
            data = { 'cust_item_code': item.cust_item_code,
                     'customer': item.customer_id,
                     'item': item.id,
                     'item_name': item.name,
                     'description': item.description,
                     'class': item.inv_class_id,
                     'group': item.inv_group_id,
                     'package': item.package_id,
                     'unit_weight': item.unit_weight,
                   }
        except:
            data = { 'error': 'An error occured.'}
    else:
        data = {'error': 'No item' }
    return JsonResponse(data)

@deny_get
def get_reclass_suggestion(request):
    receiver_from = request.POST.get('receiver_from')
    receiver = InvLog.objects.get(receiver=receiver_from)
    if receiver.inv_class_id == "FG":
        suggestion_base = receiver_from[0:6]
    elif receiver.inv_class_id == "NCM":
        suggestion_base = receiver_from[0:8]
    else:
        suggestion_base = receiver_from[0:5]  #RM or anything else
    receiver_exists = True
    counter = 1
    while receiver_exists:
        suggestion = suggestion_base + "RC" + str(counter)
        try:
            found_receiver = InvLog.objects.get(receiver=suggestion)  #found_receiver never used, but InvLog lookup required
            counter += 1
        except:
            receiver_exists = False;
    data = {'suggestion': suggestion}
    return JsonResponse(data)

# If To: does not exist and user requests new reocrd, create
@deny_get
def create_new_reclass_to(request):
    #add concurrency qty check - qty to trasnfer needs to be sent in and compared to qty on hand of from - return error if not enough
    from_receiver = request.POST.get('from_receiver', None)
    new_receiver = request.POST.get('new_receiver', None)
    reference = request.POST.get('reference', None)
    transfer_qty = request.POST.get('transfer_qty', None)
    customer = request.POST.get('customer', None)
    item = request.POST.get('item', None)
    cust_item_code = request.POST.get('cust_item_code', None)
    description = request.POST.get('description', None)
    lot = request.POST.get('lot', None)
    inv_class = request.POST.get('inv_class', None)
    group = request.POST.get('group', None)
    package = request.POST.get('package', None)
    unit_weight = request.POST.get('unit_weight', None)
    try:  #create new record.  When form submits, updates qty, remarks and adds adjustment invtrx
        new_receiver_info = InvLog.objects.get(receiver=from_receiver)
        transfer_qty_dec = Decimal(transfer_qty.replace(',',''))
        if new_receiver_info.qty_on_hand < transfer_qty_dec:  # Concurrency - if not enough, return error
            data = {'error': 'Qty on hand too low'}
        else:
            new_receiver_info.receiver = new_receiver
            new_receiver_info.customer_id = customer
            new_receiver_info.item_id = item
            new_receiver_info.cust_item_code = cust_item_code
            new_receiver_info.description = description
            new_receiver_info.lot = lot
            new_receiver_info.inv_class_id = inv_class
            new_receiver_info.group_id = group
            new_receiver_info.package_id = package
            new_receiver_info.unit_weight = Decimal(unit_weight)
            new_receiver_info.qty_on_hand = 0
            new_receiver_info.remarks = ""
            new_receiver_info.disp_remarks = ""
            new_receiver_info.save()
            # Add new invtrx with received = 0
            new_invtrx = InvTrx()
            new_invtrx.receiver_id = new_receiver
            new_invtrx.reference = reference
            new_invtrx.transaction_date = date.today()
            new_invtrx.days = 0
            new_invtrx.received = 0
            new_invtrx.trans_qty = 0
            new_invtrx.user = request.user
            new_invtrx.save()
            data = {'success': 'Created new to record'}
    except:
        data = {'error': 'An error has occurred'}
    return JsonResponse(data)


# Check if date is close date or older - return result:'' if after close, return result:'close_date' if date too old
@deny_get
def check_close_date(request):
    close_date_type = request.POST.get('close_date_type', None)
    field_value = request.POST.get('txn_date', None)
    data = {'result': ''}
    if field_value != "":
        field_split = field_value.split(' ', 1)
        the_date = field_split[0]
        txn_date = get_date(the_date)
        inv_close_date = get_global_setting(close_date_type)
        if inv_close_date is not None:
            if txn_date <= inv_close_date:
                data = {'result':inv_close_date.strftime('%m/%d/%Y')}
    return JsonResponse(data)

# Check car location entered,  If a general spot, return loc_status = "general", if a specisif spot and open, return loc_status = "open".  
# Otherwise, loc_status is name of car occupying the location or "invalid" if not a specific or general location
@deny_get
def check_car_location(request):
    location = request.POST.get('location', None)
    if location is not None:
        try:
            car_loc_site = CarLocSite.objects.get(name=location)
            if car_loc_site.type_id == "GENERAL":
                data = {'loc_status': "general"}
            elif car_loc_site.type_id == "INBOUND":
                data = {'loc_status': "inbound"}
            elif car_loc_site.type_id == "SPECIFIC":
                try:
                    car_found = CarLoc.objects.get(cloc_id=location)
                    data = {'loc_status': car_found.car.name}
                except:
                    data = {'loc_status': "open"}
            else:  # Car site not specific or general
                data = {'loc_status': "invalid"}
        except:  # site does not exist
            data = {'loc_status': "invalid"}
    else:
        data = {'loc_status': "error"}
    return JsonResponse(data)

@deny_get
def django_session(request):
    session_action = request.POST.get('session_action', None)
    session_var = request.POST.get('session_var', None)
    session_val = request.POST.get('session_val', None)
    if session_action == 'get':
        try:
            value = request.session[session_var]
            response = 'get_success'
        except:
            response = 'get_fail'
            value = 'Does not exist'
        data = {'response': response,
                'session_var': session_var,
                'value': value}
    elif session_action == 'set':
        try:
            request.session[session_var] = session_val
            response = 'set_success'
        except:
            response = 'set_fail'
            value = 'No Var'
        data = {'response': response,
                'session_var': session_var,
                'value': session_val}
    elif session_action == 'del':
        try:
            del request.session[session_var]
            response = 'del_success'
            value = session_val
        except:
            response = 'del_fail'
            value = 'Does not exist'
        data = {'response': response,
                'session_var': session_var,
                'value': value}
    else:
        data = {'response': 'invalid_action',
                'session_var': session_var,
                'value': session_val}
    return JsonResponse(data)

@deny_get
def update_cln(request):
    job_id = request.POST.get("job", None)
    new_code = request.POST.get("new_code", None)
    job_only = request.POST.get("job_only", None)
    if job_id is not None and job_id != "":
        job = JobLog.objects.get(job=job_id)
        if(job_only != '' and job_only is not None):
            pro_details = ProDetail.objects.filter(prolog__job_id=job_id).filter(code__code_class='CLN')
            for prodetail in pro_details:
                prodetail.code_id = new_code
                prodetail.save()
        job.cln_code = new_code
        job.save()
        data = {
            'status': 'success',
            'value': new_code
            }
    else:
        data = {
            'status': 'fail',
            'value': 'missing data'
            }
    return JsonResponse(data)

@deny_get
def get_frmitems(request):
    frmlog_id = request.POST.get('frmlog_id', None)
    if frmlog_id is not None:
        try:
            frmitems = FrmItem.objects.filter(frmlog=frmlog_id).annotate(pct=F('tgt')*Decimal(100.0)/FrmItem.objects.filter(frmlog=frmlog_id).aggregate(Sum('tgt'))['tgt__sum']).order_by('sequence')
            total_pct = frmitems.aggregate(Sum('pct'))['pct__sum']
            #for frmitem in frmitems:
            #    total_pct = total_pct + frmitem.tgt
            html = render_to_string('informant_erp/fragments/fdr_frmitems.html', {'frmitems': frmitems, 'total_pct': total_pct})
            return HttpResponse(html)
        except:
            data = {'error': 'An error occurred'}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

@deny_get
def test_fdr_unique(request):
    frmlog_id = request.POST.get('frmlog_id', None)
    line = request.POST.get('line', None)
    unique = True
    feeder_types = []
    error = ""
    record_id = -1
    if frmlog_id is not None and line is not None:
        try:
            feeder_types = list(LineFeedSystem.objects.filter(line_id=line).order_by('feeder_id').values())
            existing_fdrlog = FdrLog.objects.filter(frmlog_id=frmlog_id).filter(line=line).first()
            if existing_fdrlog:
                unique = False
                record_id = existing_fdrlog.pk
                error = "Duplicate Feeder Setup."
            else:
                error = "Line not in LineFeedSystem."
        except:
            error = "An error occurred."
    else:
        error = "Missing Data."
        
    if feeder_types and unique:
        data = {'unique': unique,
                'feeder_types': feeder_types,
                'error': error}
    else:
        data = {'error': error,
                'value': record_id}
    return JsonResponse(data)

@deny_get
def get_feeder_type(request):
    line = request.POST.get('line', None)
    feeder = request.POST.get('feeder', None)
    if line is not None and feeder is not None:
        try:
            feeder_type = LineFeedSystem.objects.get(line_id=line, feeder_id=feeder).feeder_type_id
            data = {'found': True,
                    'value': feeder_type}
        except:
            data = {'error': 'An error occurred'}
    else:
        data = {'error': 'Missing Data'}
    return JsonResponse(data)

# Get all fields from record and return ajax function - fills entire form with 'borrowed' data from another record
@deny_get
def get_runlog_borrowed(request):
    fdrlog_id = request.POST.get('fdrlog_id', None)
    try:   
        runlog = RunLog.objects.get(fdrlog_id=fdrlog_id)
        data = {'z1': runlog.z1,
                'z2': runlog.z2,
                'z3': runlog.z3,
                'z4': runlog.z4,
                'z5': runlog.z5,
                'z6': runlog.z6,
                'z7': runlog.z7,
                'z8': runlog.z8,
                'z9': runlog.z9,
                'z10': runlog.z10,
                'z11': runlog.z11,
                'z12': runlog.z12,
                'z13': runlog.z13,
                'z14': runlog.z14,
                'die':runlog.die,
                'melt': runlog.melt,
                'screw': runlog.screw,
                'feed_rate': runlog.feed_rate,
                'rpm1': runlog.rpm1,
                'pwr1': runlog.pwr1,
                'rpm2': runlog.rpm2,
                'pwr2': runlog.pwr2,
                'nitrogen': runlog.nitrogen,
                'vent1': runlog.vent1,
                'vent2': runlog.vent2,
                'vent3': runlog.vent3,
                'up_press': runlog.up_press,
                'dn_press': runlog.dn_press,
                'screen_pack': runlog.screen_pack,
                'die_size': runlog.die_size,
                'die_holes': runlog.die_holes,
                'die_pattern': runlog.die_pattern,
                'spring': runlog.spring,
                'blades': runlog.blades,
                'cutter_rpm': runlog.cutter_rpm,
                'pipe': runlog.pipe,
                'water_temp': runlog.water_temp,
                'pelletizer': runlog.pelletizer,
                'water_bath': runlog.water_bath,
                'air_knife': runlog.air_knife,
                'class_hole_size': runlog.class_hole_size,
                'metal_sep': runlog.metal_sep,
                'setup_notes': runlog.setup_notes,
                }
    except:
        data = {'error': 'Item does not exist'}
    return JsonResponse(data)

# Get all fields from record and return ajax function - fills entire form with 'borrowed' data from another record
@deny_get
def get_frmlog_borrowed(request):
    frmlog_id = request.POST.get('frmlog_id', None)
    try:   
        frmlog = FrmLog.objects.get(id=frmlog_id)
        frmitems = FrmItem.objects.filter(frmlog=frmlog)
        results = []
        for frmitem in frmitems:
            item = {}
            item['item'] = frmitem.item_id
            item['item_disp'] = frmitem.item.name 
            item['item_customer'] = frmitem.item_customer_id
            item['tgt'] = frmitem.tgt 
            item['adjust'] = frmitem.adjust 
            item['min'] = frmitem.min 
            item['max'] = frmitem.max 
            item['link_id'] = frmitem.link_id  
            item['link_total'] = frmitem.link_total 
            results.append(item)
        data = {'frmitems': json.dumps(results, cls=DecimalEncoder)
                }
    except Exception as e:
        print (getattr(e, 'message', repr(e)))
        data = {'error': 'Item does not exist'}
    return JsonResponse(data)

@deny_get
def get_rec_info(request):
    receiver_id = request.POST.get('receiver_id', None)
    if receiver_id is not None:
        try:
            receiver_info = InvLog.objects.get(receiver=receiver_id)
            data = {'item': receiver_info.item.name,
                    'qty': receiver_info.qty_on_hand}
        except:
            data = {'error': 'Receiver does not exist'}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

@deny_get
def get_frmdrw_list(request):
    frmlog_id = request.POST.get('frmlog_id', None)
    if frmlog_id is not None:
        try:
            frmdevrws = FrmDevRw.objects.filter(frmlog=frmlog_id)
            html = render_to_string('informant_erp/fragments/frm_devrw_list.html', {'frmdevrws': frmdevrws})
            return HttpResponse(html)
        except:
            data = {'error': 'An error occurred'}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

#Get ID of prolog based on unique fields date, shift, line, job
@deny_get
def get_prolog_id(request):
    raw_date = request.POST.get('date', None)
    pro_date = get_date(raw_date)
    shift = request.POST.get('shift', None)
    line = request.POST.get('line', None)
    job = request.POST.get('job', None)
    if job == '':
        job=None
    try:
        if job:
            prolog_id = ProLog.objects.get(date=pro_date, shift=shift, line_id=line, job_id=job).id  # This should ais an exception if there is no record
        else:
            prolog = ProLog.objects.filter(date=pro_date, shift=shift, line_id=line).filter(job_id__isnull=True).first()
            prolog_id = prolog.id # This should raise an exception of prolog is None
        data = {'id': prolog_id}
    except:
        data = {'id': 'not-found'}
    return JsonResponse(data)

# Calls to return job info and any existing data for the job complete form integrated in inv_production
@deny_get
def job_complete_info(request):
    job_id = request.POST.get('job', None)
    if job_id is not None:
        try:
            job_info = JobLog.objects.filter(job=job_id).first()
            html = render_to_string('informant_erp/fragments/job_complete_info.html', {'joblog': job_info})
            return HttpResponse(html)
        except Exception as error:
            data = {'error': 'An error occurred:' + str(error)}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

def date_to_string(date):
    if date:
        string = date.strftime('%m/%d/%Y %H:%M')
    else:
        string = ""

    return string


@deny_get
def job_complete_form_data(request):
    job_id = request.POST.get('job', None)
    if job_id is not None:
        try:
            job_info = JobLog.objects.get(job=job_id) 
            data = {
                'status': job_info.status_id,
                'job_start': date_to_string(job_info.job_start),
                'job_complete': date_to_string(job_info.job_complete),
                'prod_cert': date_to_string(job_info.prod_cert),
                'lab_cert': date_to_string(job_info.lab_cert),
                'cs_cert': date_to_string(job_info.cs_cert),
                'cust_sys': date_to_string(job_info.cust_sys),
                'job_remarks': job_info.remarks,
                }
        except:
            data = {'error': 'An error occurred'}
    else:
        data = {'error': 'No Data'}
    return JsonResponse(data)

@deny_get
def cic_update(request):
    item_id = request.POST.get("item_id", None)
    new_code = request.POST.get("new_code", None)
    if item_id is not None and item_id != "":
        item = Item.objects.get(pk=item_id)
        item.cust_item_code = new_code
        item.save()
        data = {
            'success': True,
            'status': 'success',
            'value': new_code
            }
    else:
        data = {
            'success': False,
            'status': 'fail',
            'value': 'missing data'
            }
    return JsonResponse(data)

@deny_get
def check_duplicate_invmin(request):
    item_id = request.POST.get("item_id", None) 
    customer_id = request.POST.get("customer_id", None)
    p_category_id = request.POST.get("p_category_id", None)
    try:
        invmin_id = InvMin.objects.get(item_id=item_id, customer_id=customer_id, p_category_id=p_category_id).id
        data = {'id': invmin_id,
                'duplicate': True}
    except:
        data = {'id': 'not-found',
                'duplicate': False}
    
    return JsonResponse(data)

@deny_get
def get_receiver_info(request):
    receiver = request.POST.get('receiver', None)
    invlog = InvLog.objects.filter(receiver=receiver).first()
    if invlog:
        data = {'receiver': invlog.receiver,
                'lot': invlog.lot,
                'item': invlog.item.name,
                'slug': invlog.slug}
    else:
        data = {'receiver': 'not-found'}
    return JsonResponse(data)

@deny_get
def ncm_update_next(request):
    # Get all input
    direction = request.POST.get('direction', None)
    ncm = request.POST.get('ncm', None)
    line = request.POST.get('line', None)
    reason = request.POST.get('reason', None)
    result = request.POST.get('result', None)
    disposition = request.POST.get('disposition', None)
    location = request.POST.get('location', None)
    job = request.POST.get('job', None)
    shift = request.POST.get('shift', None)
    prolog_date = request.POST.get('date', None)
    produced = request.POST.get('produced', None)
    consumed = request.POST.get('consumed', None)
    updated = False
    if produced == '':
        produced = Decimal(0.0)
    else:
        produced = Decimal(produced.replace(',',''))
    if consumed == '':
        consumed = Decimal(0.0)
    else:
        consumed = Decimal(consumed.replace(',',''))
    if reason == '':
        reason = None
    if disposition == '':
        disposition = None
    if result == '':
        result = None
    if line == '':
        line = None

    # Get NCM list based on job in NCM order
    ncm_list = NCMLog.objects.filter(reference=job).order_by('ncm')
    try:
        current_rec = NCMLog.objects.get(ncm=ncm)
    except:
        current_rec = None
        data = {'next_record': False}

    # Get next and previous ncm_id, wrap
    ncms = list(ncm_list.values_list('ncm', flat=True))
    current_pos = ncms.index(current_rec.ncm)
    if current_pos < len(ncms) - 1:
        next_id = ncms[current_pos + 1]
    if current_pos == len(ncms)-1:
        next_id = ncms[0]
    if current_pos > 0:
        previous_id = ncms[current_pos - 1]
    if current_pos == 0:
        previous_id = ncms[len(ncms)-1]

    try:
        if direction == 'next':
            next_rec = NCMLog.objects.get(ncm=next_id)
        else:
            next_rec = NCMLog.objects.get(ncm=previous_id)
    except:
        next_rec = None
        data = {'next_record': False}

    # Update current record with current form data
    if reason != current_rec.reason_id or disposition != current_rec.disposition_id or result != current_rec.result or produced != Decimal(0.0) or consumed != Decimal(0.0) or line != current_rec.ncmline_id:
        current_rec.result = result
        current_rec.ncmline_id = line
        if reason != '':
            current_rec.reason_id = reason
        else:
            current_rec.reason_id = None
        if disposition != '':
            current_rec.disposition_id = disposition
        else:
            current_rec.disposition_id = None

        if produced != Decimal(0.0) or consumed != Decimal(0.0):
            current_rec.qty_on_hand = current_rec.qty_on_hand + produced - consumed

        current_rec.save() # Save any changes to NCMLog
        new_ncmtrx(current_rec, shift, prolog_date, str(produced), str(consumed), location, request.user)  #Add new NCMTrx
        updated = True

    data = {'next_record': True,
            'updated': updated,
            'ncm': next_rec.ncm,
            'line': next_rec.ncmline_id,
            'reference': next_rec.reference_id,
            'reason': next_rec.reason_id,
            'result': next_rec.result   ,
            'qty_on_hand': int(next_rec.qty_on_hand),
            'disposition': next_rec.disposition_id}
    return JsonResponse(data)

# Autofill certain fields from joblog selected in job product
@deny_get
def set_django_message(request):
    message = request.POST.get('message', None)
    type = request.POST.get('type', None)
    if message is not None and type is not None:
        if type == "warning":
            messages.warning(request, message)
        elif type == "error":
            messages.error(request, message)
        else:
            messages.success(request, message)
        data = {'msg': 'Message set'}
    return JsonResponse(data)