Source code for core.functions

from core.models import Addition,Location,ShipUnit,LocationType,WineLocationValues,Account
from django.db.models import Sum


#from poc.alloc.models import wine_location

# ============ Function Summary
# allocate :  put away in location case, bin or rack
# receive: for orders -  set status to received, add to temp location
# type_capacity: return total capacity of Bin and Rack location types
# capacity: return the total capacity available for the location type
# bin_capacity_ct : the number of bins with allocation capacity
# 

# ==========================================================================

[docs] def get_account_name(request): current_user = request.user return current_user.account
[docs] def get_account_id(owner): account_id = Account.objects.get(account=owner) return account_id.id return current_user.account
[docs] def next_case(owner): type_key = LocationType.objects.get(location_type='Case') get_cases = Location.objects.filter(type_id=type_key,account=owner).values() case_ct = get_cases.count() case_ct = int(case_ct) + 1 case_str = str(case_ct).zfill(4) case_name = 'CS' + case_str #print('case name = ',case_name) return case_name
[docs] def type_capacity(owner): #return the capacity of Bin and Rack location types (Bins & Rack) #get bin and location keys bin_capacity = capacity(2,owner) empty_rack_items = empty_rack_slots(owner) rack_capacity = len(empty_rack_items) #print('Rack capacity returned',rack_capacity) return bin_capacity,rack_capacity
[docs] def capacity(type_key,owner): #return the total capacity available for the location type num_ct = 0 max_capacity = 0 tot_max_capacity = 0 #print('1 get capacity for ', type_key) chk=LocationType.objects.get(pk=type_key) # get objects for this type max_capacity = chk.location_max_qty #get the max qty for this location type #print('2. max_capacity = ',max_capacity) num_ct = Location.objects.filter(type_id=type_key,account=owner).count() # get the number of these locations #print('3. num_ct',num_ct) if num_ct == 0: # print('4.1 num ct = 0',num_ct) capacity = 0 #used capacity # print('4.1 capacity = 0',capacity) tot_max_capacity = max_capacity # print('4.1 tot max capacity = ',tot_max_capacity) else: #print('**** in the else 4.2') tot_max_capacity = (max_capacity * num_ct) calc_capacity = Location.objects.filter(type_id=type_key).aggregate(Sum('location_qty')) capacity = calc_capacity['location_qty__sum'] # sum of all locations #print('tot max capacity =',tot_max_capacity) #print('capacity = ',capacity) available_capacity = tot_max_capacity - capacity #print('available capacity = ',available_capacity) return available_capacity
[docs] def bin_capacity_ct(rqt): #return the number of bins with enough capacity for the requirement(rqt) #Note we only need to check count of bins # get bin type # get all bins from wine_locations # If nore than 1 then for each bin check get capacity, # return values max_capacity = 0 used_capacity = 0 available_capacity = 0 bins_list = [] bins = LocationType.objects.get(Location_type='Bin').pk all_bins_ct = bins.count() print('bin count = ', all_bins_ct) if all_bins_ct ==1: qty=bins.location_qty max_qty = bins.location_max_qty free_qty = max_qty - qty if free_qty >0: bins_list.insert(bins.pk,'free_qty') elif all_bins_ct > 1: for n in bins: qty=n.location_qty max_qty = n.location_max_qty free_qty = max_qty - qty if free_qty > 0: bins_list.insert(n.pk,'free_qty') return bins_list
[docs] def allocate(wine_id,allocation_type,alloc_loc,owner): # wine_id = unique wine identifier # Allocation type: Case allocations = create case. Bins and Racks must exist, Create case # alloc_loc = optional parameter (not needed for cases as the cases id is created dynamically when called ) # owner = account id # No constraint on number in a cellar # Fix 28 April for allocation quantity # Allocation qty for Case and Bin = Quantity - Allocation Quantity # Allocation qty for Rack = Allocation Quantity + 1 ( racks hold 1 unit) # Temp Location : reduce Temp Qty by allocation Quantity val # Set Addition status to part allocated or put away print('Allocate : Allocation details = ', wine_id,allocation_type,alloc_loc,flush=True) #Update Wine allocation fields : alloc qty and allocation status wine = Addition.objects.get(pk=wine_id) if allocation_type == 'Rack': # Allocate a single bottle alloc_qty = 1 wine.allocation_qty = wine.allocation_qty + 1 if wine.allocation_qty < wine.quantity : #check if part allocated or not wine.addition_status = 'Part Allocated' else: wine.addition_status = 'Put Away' else: #Set status to Put away, set allocation qty to remaining number left to allocate as as user may have been allocated some to rack # For both Bins and cases the allocation quantity is the remaining quantity left to allocate alloc_qty = wine.quantity - wine.allocation_qty # set alloc qty to delivery quantity wine.allocation_qty = wine.allocation_qty + alloc_qty wine.addition_status = 'Put Away' print('Allocate : wine allocation qty after assignment =',wine.allocation_qty,flush=True) # Update Wine Object with Allocation Status try: wine.save() print('Allocate Wine object - allocation status updated',flush=True) except: print('Wine object update failed',flush=True) # If a case allocation create a new case with the alloc qty set to the remaining number to allocate if allocation_type == 'Case': # Create a New Case and update the location quantity case_name = next_case(owner) alloc_loc=case_name # set the allocation location to the new case case_account = get_account_id(owner) print(case_name,wine.allocation_qty,case_account) new_case = Location(name = case_name,location_qty=alloc_qty, type_id = '3',account_id=case_account) try: new_case.save() print('Create New Case - success',flush=True) except: print('** Fail to create new case',flush=True) else : # Update Location details for Bin and Rack allocations # Get location details and update quantity loctn = Location.objects.get(name=alloc_loc,account_id=owner) loctn.location_qty = loctn.location_qty + alloc_qty # add this allocation quantity to current location qty # save the new location quantity try: # Save Location loctn.save() print( 'Allocate: Location details update Success',flush=True ) print('Location details =',loctn.location_qty,loctn.id,loctn.type,flush=True) except: print( 'Allocate - Update Location details - fail line 296',flush=True ) # Update (M2M) addition_location new_location = Location.objects.get(name=alloc_loc,account_id=owner) try: wine.wine_location.add(new_location) print ('Allocate - save M2M : Success ',flush=True) except: print('Allocate: M2M save error',flush=True) print(' Allocate : allocation quantity var= ',alloc_qty,flush=True) print(' wine details to save : allocated ',wine.allocation_qty,flush=True) # get latest wine values , statuses etc. wine = Addition.objects.get(pk=wine_id) #Process temp location records if wine.addition_status == 'Put Away': # delete the temp location record try: t = Location.objects.get(type_id=1,name=wine_id,account=owner) # get temp record details for this wine t.delete() print('Allocate - Temp object process delete success, wine now put away') except: print('Allocate - No temp object in Location table for this wine ') # Update WineLocation Values loctn = Location.objects.get(name=alloc_loc,account=owner) wlv_qty = 0 # set this to 1 if rack else set it it to alloc qty if allocation_type == 'Rack': wlv_qty = 1 else: wlv_qty = alloc_qty try: wlv_price = (wine.price + wine.duty + wine.ship_costs)/wine.allocation_qty print ( 'Allocate - SUCCESS wlv price set') except: wlv_price = 0 print ( 'Allocate - ERROR setting wlv price - price set to 0') new_wlv = WineLocationValues(wine_id=wine.pk, quantity=wlv_qty, style=wine.style, country=wine.country, vintage=wine.year, size=wine.size, price = wlv_price, location_id=loctn.pk, location_type=loctn.type, account=owner) try: new_wlv.save() print('Allocate - Update WineLocationValues New record added') except: print('Allocate - Update WineLocationValues Failed line 211')
[docs] def receive(wine_id): # set addition status to Received for Ordered wines # add to temp location # update wine_location ( see add wine for an example ) wine = Addition.objects.get(pk=wine_id) qty = wine.quantity # the number of individual bottles # Build Location update and save new_location =Location(name = wine.id, location_qty = qty, type_id = '1', ) # save new_location.save() wine.wine_location.add(new_location) wine.addition_status = 'Received' wine.save()
[docs] def addition_check(owner): error_list=[] status_check = 'success' ac = owner #errormsg = str('A list of the errors found when running addition check') #error_list.append(errormsg) #error_list.append('\n') #errormsg = str('Go to \info\audit\errrors to see how to fix each possible error') #error_list.append(errormsg) #error_list.append('\n') total_wine_qty=0 total_wlv_qty =0 addition_records = Addition.objects.filter(quantity__gt=0,addition_status='Put Away')|Addition.objects.filter(quantity__gt=0,addition_status='Tried') addition_records = addition_records.filter(account_id=ac) w= WineLocationValues.objects.filter(account_id=ac) for x in addition_records: # iterate thru additions and check qty against wlv qty total_wine_qty = total_wine_qty+x.quantity # so we can check total qty of addition matches total wlv wine_id_qty = x.quantity # now check each addition item wlv_id_qty=0 # set the id to 0 as we start the process wcheck = w.filter(wine_id=x.id) # get wlv records for this wine id wcount = wcheck.count() #count how many records have been found if wcount > 0: # we have found record(s) so can iterate through each one wcounter = 0 # wcounter used to see how many wlv records found for z in wcheck: wcounter = wcounter +1 # increment counter wlv_id_qty =wlv_id_qty + z.quantity # get the wlv quantity for this wine else: status_check = 'errors' str_id=str(x.id) errormsg = 'No Wine Location records found for ' + str(x.name) + ' ID(' + str_id + ') Quantity = ' + str(x.quantity) error_list.append(errormsg) #error_list.append('\n') if wcount != 0: if wlv_id_qty != wine_id_qty : status_check = 'errors' str_id=str(x.id) errormsg='Location quantity mismatch for ' + str(x.name) + ' ID(' + str_id + ') Quantity = ' + str(x. quantity) + ' Wine Location qty = ' + str(wlv_id_qty) + ' Wine location records are :' + str(wcheck) error_list.append(errormsg) error_list.append('\n') return status_check,error_list
[docs] def empty_rack_slots(owner): # iterates through all rack slots for an account building a list of empty slots empty_slot_list=[] # Create the list cellar_locations = Location.objects.filter(type_id='4',account=owner) # Get rack slots for l in cellar_locations: #Iterate through each location # check if the are any wines in the location # print(l.name, l.id,l.location_qty,l.account) wlv = WineLocationValues.objects.filter(location_id = l.id,account=l.account) if not wlv: # If no records then this is an empty slot - add to the list empty_slot_list.append(l.name) return empty_slot_list