Added site planners to list generation
This commit is contained in:
parent
faafa75422
commit
160c21427d
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -314,6 +314,7 @@ def postGeneratedList():
|
|||||||
payload: dict = request.get_json()
|
payload: dict = request.get_json()
|
||||||
site_name: str = session['selected_site']
|
site_name: str = session['selected_site']
|
||||||
user_id: int = session['user_id']
|
user_id: int = session['user_id']
|
||||||
|
print(payload)
|
||||||
shoplist_processess.postNewGeneratedList(site_name, payload, user_id)
|
shoplist_processess.postNewGeneratedList(site_name, payload, user_id)
|
||||||
return jsonify(status=201, message=f"List Generated successfully!")
|
return jsonify(status=201, message=f"List Generated successfully!")
|
||||||
return jsonify(status=405, message=f"{request.method} is not an accepted method on this endpoint!")
|
return jsonify(status=405, message=f"{request.method} is not an accepted method on this endpoint!")
|
||||||
@ -324,6 +324,36 @@ def getItemByUUID(site, payload:dict, convert=True, conn=None):
|
|||||||
except Exception as error:
|
except Exception as error:
|
||||||
raise postsqldb.DatabaseError(error, payload, sql)
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
|
|
||||||
|
def getEventRecipes(site, payload, convert=True, conn=None):
|
||||||
|
""" payload: dict = {'plan_uuid', 'start_date', 'end_date'}"""
|
||||||
|
records = ()
|
||||||
|
self_conn = False
|
||||||
|
with open('application/shoppinglists/sql/getEventsRecipes.sql', 'r') as file:
|
||||||
|
sql = file.read().replace("%%site_name%%", site)
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
if not conn:
|
||||||
|
database_config = config.config()
|
||||||
|
conn = psycopg2.connect(**database_config)
|
||||||
|
conn.autocommit = True
|
||||||
|
self_conn = True
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql, payload)
|
||||||
|
rows = cur.fetchall()
|
||||||
|
if rows and convert:
|
||||||
|
records = [postsqldb.tupleDictionaryFactory(cur.description, row) for row in rows]
|
||||||
|
elif rows and not convert:
|
||||||
|
records = rows
|
||||||
|
|
||||||
|
if self_conn:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return records
|
||||||
|
except Exception as error:
|
||||||
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
|
|
||||||
def deleteShoppingListsTuple(site_name, payload, convert=True, conn=None):
|
def deleteShoppingListsTuple(site_name, payload, convert=True, conn=None):
|
||||||
deleted = ()
|
deleted = ()
|
||||||
self_conn = False
|
self_conn = False
|
||||||
|
|||||||
@ -48,6 +48,7 @@ def postNewGeneratedList(site: str, data: dict, user_id: int, conn=None):
|
|||||||
recipes: list = data['recipes']
|
recipes: list = data['recipes']
|
||||||
full_system_calculated: list = data['full_system_calculated']
|
full_system_calculated: list = data['full_system_calculated']
|
||||||
shopping_lists: list = data['shopping_lists']
|
shopping_lists: list = data['shopping_lists']
|
||||||
|
site_plans: list = data['site_plans']
|
||||||
|
|
||||||
|
|
||||||
self_conn=False
|
self_conn=False
|
||||||
@ -158,6 +159,26 @@ def postNewGeneratedList(site: str, data: dict, user_id: int, conn=None):
|
|||||||
items_to_add_to_system.append(temp_item)
|
items_to_add_to_system.append(temp_item)
|
||||||
|
|
||||||
|
|
||||||
|
if site_plans:
|
||||||
|
for site_plan in site_plans:
|
||||||
|
if site_plan['plan_uuid'] == 'site': site_plan['plan_uuid'] = None
|
||||||
|
plan_recipes = [event['recipe_uuid'] for event in shoplist_database.getEventRecipes(site, site_plan, conn=conn)]
|
||||||
|
if plan_recipes:
|
||||||
|
for recipe_uuid in plan_recipes:
|
||||||
|
recipe_items = shoplist_database.getRecipeItemsByUUID(site, (recipe_uuid,), conn=conn)
|
||||||
|
for item in recipe_items:
|
||||||
|
temp_item = database_payloads.ShoppingListItemPayload(
|
||||||
|
list_uuid=shopping_list['list_uuid'],
|
||||||
|
item_type='recipe',
|
||||||
|
item_name=item['item_name'],
|
||||||
|
uom=item['uom'],
|
||||||
|
qty=float(item['qty']),
|
||||||
|
item_uuid=item['item_uuid'],
|
||||||
|
links=item['links']
|
||||||
|
)
|
||||||
|
items_to_add_to_system.append(temp_item)
|
||||||
|
|
||||||
|
|
||||||
if items_to_add_to_system:
|
if items_to_add_to_system:
|
||||||
for item in items_to_add_to_system:
|
for item in items_to_add_to_system:
|
||||||
shoplist_database.insertShoppingListItemsTuple(site, item.payload(), conn=conn)
|
shoplist_database.insertShoppingListItemsTuple(site, item.payload(), conn=conn)
|
||||||
@ -180,8 +201,10 @@ def deleteShoppingList(site: str, data: dict, user_id: int, conn=None):
|
|||||||
shopping_list_items = [item['list_item_uuid'] for item in shopping_list_items]
|
shopping_list_items = [item['list_item_uuid'] for item in shopping_list_items]
|
||||||
|
|
||||||
shoplist_database.deleteShoppingListsTuple(site, (shopping_list_uuid,), conn=conn)
|
shoplist_database.deleteShoppingListsTuple(site, (shopping_list_uuid,), conn=conn)
|
||||||
|
if shopping_list_items:
|
||||||
shoplist_database.deleteShoppingListItemsTuple(site, shopping_list_items, conn=conn)
|
shoplist_database.deleteShoppingListItemsTuple(site, shopping_list_items, conn=conn)
|
||||||
|
|
||||||
|
|
||||||
if self_conn:
|
if self_conn:
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
7
application/shoppinglists/sql/getEventsRecipes.sql
Normal file
7
application/shoppinglists/sql/getEventsRecipes.sql
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
SELECT events.recipe_uuid
|
||||||
|
FROM %%site_name%%_plan_events events
|
||||||
|
WHERE events.plan_uuid IS NULL
|
||||||
|
AND events.event_type = 'recipe'
|
||||||
|
AND events.recipe_uuid IS NOT NULL
|
||||||
|
AND events.event_date_start <= %(end_date)s
|
||||||
|
AND events.event_date_end >= %(start_date)s;
|
||||||
@ -1076,6 +1076,130 @@ async function generateListsTable() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Site Planner Functions
|
||||||
|
var site_planners = {}
|
||||||
|
var site_planner_card_active = false;
|
||||||
|
async function addPlannerCard(){
|
||||||
|
if(!site_planner_card_active){
|
||||||
|
document.getElementById('plannerCard').hidden = false
|
||||||
|
site_planner_card_active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function removePlannerCard(){
|
||||||
|
document.getElementById('plannerCard').hidden = true
|
||||||
|
site_planner_card_active = false;
|
||||||
|
site_planners = []
|
||||||
|
}
|
||||||
|
|
||||||
|
var PlannerZoneState = true
|
||||||
|
async function changePlannerZoneState() {
|
||||||
|
PlannerZoneState = !PlannerZoneState
|
||||||
|
document.getElementById('plannerZone').hidden = !PlannerZoneState
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openPlannerModal(){
|
||||||
|
document.getElementById('planUUID').setAttribute('class', 'uk-input uk-disabled')
|
||||||
|
document.getElementById('planUUID').value = 'site'
|
||||||
|
document.getElementById('planStartDate').value = ''
|
||||||
|
document.getElementById('planEndDate').value = ''
|
||||||
|
document.getElementById('plannerModalButton').innerHTML = "Save"
|
||||||
|
document.getElementById('plannerModalButton').onclick = async function () { await addPlanner()}
|
||||||
|
UIkit.modal(document.getElementById('plannerModal')).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addPlanner() {
|
||||||
|
var planner_select = document.getElementById('planUUID')
|
||||||
|
planner_uuid = planner_select.value
|
||||||
|
plan_name = planner_select.options[planner_select.selectedIndex].text
|
||||||
|
startDate = document.getElementById('planStartDate').value
|
||||||
|
endDate = document.getElementById('planEndDate').value
|
||||||
|
site_planners[planner_uuid] = {
|
||||||
|
start_date: startDate,
|
||||||
|
end_date: endDate,
|
||||||
|
plan_uuid: planner_uuid,
|
||||||
|
plan_name: plan_name
|
||||||
|
}
|
||||||
|
UIkit.modal(document.getElementById('plannerModal')).hide()
|
||||||
|
console.log(site_planners)
|
||||||
|
await generatePlannerTable()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function editPlanner(planUUID) {
|
||||||
|
let data = site_planners[planUUID]
|
||||||
|
document.getElementById('planUUID').setAttribute('class', 'uk-input uk-disabled')
|
||||||
|
document.getElementById('planUUID').value = data['plan_uuid']
|
||||||
|
document.getElementById('planStartDate').value = data['start_date']
|
||||||
|
document.getElementById('planEndDate').value = data['end_date']
|
||||||
|
document.getElementById('plannerModalButton').innerHTML = "Save"
|
||||||
|
document.getElementById('plannerModalButton').onclick = async function () {
|
||||||
|
var planner_select = document.getElementById('planUUID')
|
||||||
|
planner_uuid = planner_select.value
|
||||||
|
plan_name = planner_select.options[planner_select.selectedIndex].text
|
||||||
|
startDate = document.getElementById('planStartDate').value
|
||||||
|
endDate = document.getElementById('planEndDate').value
|
||||||
|
site_planners[planner_uuid] = {
|
||||||
|
start_date: startDate,
|
||||||
|
end_date: endDate,
|
||||||
|
plan_uuid: planner_uuid,
|
||||||
|
plan_name: plan_name
|
||||||
|
}
|
||||||
|
|
||||||
|
await generatePlannerTable()
|
||||||
|
UIkit.modal(document.getElementById('plannerModal')).hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
UIkit.modal(document.getElementById('plannerModal')).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function deletePlan(plannerUUID) {
|
||||||
|
delete site_planners[plannerUUID]
|
||||||
|
await generatePlannerTable()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generatePlannerTable() {
|
||||||
|
let plannerTableBody = document.getElementById('plannerTableBody')
|
||||||
|
plannerTableBody.innerHTML = ""
|
||||||
|
|
||||||
|
for(const key in site_planners){
|
||||||
|
if(site_planners.hasOwnProperty(key)){
|
||||||
|
let tableRow = document.createElement('tr')
|
||||||
|
|
||||||
|
|
||||||
|
let nameCell = document.createElement('td')
|
||||||
|
nameCell.innerHTML = `${site_planners[key].plan_name}`
|
||||||
|
|
||||||
|
let startCell = document.createElement('td')
|
||||||
|
startCell.innerHTML = `${site_planners[key].start_date}`
|
||||||
|
|
||||||
|
let endCell = document.createElement('td')
|
||||||
|
endCell.innerHTML = `${site_planners[key].end_date}`
|
||||||
|
|
||||||
|
let opCell = document.createElement('td')
|
||||||
|
|
||||||
|
let editButton = document.createElement('button')
|
||||||
|
editButton.setAttribute('class', 'uk-button uk-button-default uk-button-small')
|
||||||
|
editButton.setAttribute('uk-tooltip', 'Edits this rows plan dates.')
|
||||||
|
editButton.innerHTML = "Edit"
|
||||||
|
editButton.onclick = async function() {await editPlanner(site_planners[key].plan_uuid)}
|
||||||
|
|
||||||
|
|
||||||
|
let removeButton = document.createElement('button')
|
||||||
|
removeButton.setAttribute('class', 'uk-button uk-button-default uk-button-small')
|
||||||
|
removeButton.setAttribute('uk-tooltip', 'Removes Shopping List from the saved shopping lists')
|
||||||
|
removeButton.innerHTML = "Remove"
|
||||||
|
removeButton.onclick = async function() {await deletePlan(site_planners[key].plan_uuid)}
|
||||||
|
|
||||||
|
opCell.append(editButton, removeButton)
|
||||||
|
|
||||||
|
tableRow.append(nameCell, startCell, endCell, opCell)
|
||||||
|
plannerTableBody.append(tableRow)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Generate Functions
|
// Generate Functions
|
||||||
async function postGenerateList() {
|
async function postGenerateList() {
|
||||||
@ -1088,7 +1212,8 @@ async function postGenerateList() {
|
|||||||
calculated_items: Object.keys(calculated_items),
|
calculated_items: Object.keys(calculated_items),
|
||||||
recipes: Object.keys(recipes),
|
recipes: Object.keys(recipes),
|
||||||
full_system_calculated: full_sku_enabled,
|
full_system_calculated: full_sku_enabled,
|
||||||
shopping_lists: Object.keys(shopping_lists)
|
shopping_lists: Object.keys(shopping_lists),
|
||||||
|
site_plans: Object.values(site_planners)
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(`/shopping-lists/api/postGeneratedList`, {
|
const response = await fetch(`/shopping-lists/api/postGeneratedList`, {
|
||||||
@ -1098,4 +1223,5 @@ async function postGenerateList() {
|
|||||||
},
|
},
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
});
|
});
|
||||||
|
location.href = "/shopping-lists"
|
||||||
}
|
}
|
||||||
@ -23,30 +23,55 @@ async function replenishLineTable(sl_items){
|
|||||||
listItemsTableBody.innerHTML = ""
|
listItemsTableBody.innerHTML = ""
|
||||||
console.log(sl_items)
|
console.log(sl_items)
|
||||||
|
|
||||||
for(let i = 0; i < sl_items.length; i++){
|
let grouped = sl_items.reduce((accumen, item) => {
|
||||||
let tableRow = document.createElement('tr')
|
if (!accumen[item.item_type]) {
|
||||||
|
accumen[item.item_type] = [];
|
||||||
|
}
|
||||||
|
accumen[item.item_type].push(item);
|
||||||
|
return accumen;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
console.log(grouped)
|
||||||
|
for(let key in grouped){
|
||||||
|
console.log(key)
|
||||||
|
let items = grouped[key]
|
||||||
|
let headerRow = document.createElement('tr')
|
||||||
|
let headerCell = document.createElement('td')
|
||||||
|
headerCell.colSpan = 3;
|
||||||
|
headerCell.textContent = key.toUpperCase();
|
||||||
|
headerCell.className = 'type-header';
|
||||||
|
headerCell.style = `font-weight: bold;background: #eee; text-align: left;`
|
||||||
|
headerRow.appendChild(headerCell);
|
||||||
|
listItemsTableBody.appendChild(headerRow);
|
||||||
|
|
||||||
|
for(let i = 0; i < items.length; i++){
|
||||||
|
console.log(items)
|
||||||
|
let tableRow = document.createElement('tr')
|
||||||
|
let item = items[i]
|
||||||
let checkboxCell = document.createElement('td')
|
let checkboxCell = document.createElement('td')
|
||||||
checkboxCell.innerHTML = `<label><input class="uk-checkbox" type="checkbox" ${sl_items[i].list_item_state ? 'checked' : ''}></label>`
|
checkboxCell.innerHTML = `<label><input class="uk-checkbox" type="checkbox" ${item.list_item_state ? 'checked' : ''}></label>`
|
||||||
checkboxCell.onclick = async function (event) {
|
checkboxCell.onclick = async function (event) {
|
||||||
await updateListItemState(sl_items[i].list_item_uuid, event.target.checked)
|
console.log(item)
|
||||||
|
await updateListItemState(item.list_item_uuid, event.target.checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
namefield = sl_items[i].item_name
|
namefield = items[i].item_name
|
||||||
if(sl_items[i].links.hasOwnProperty('main')){
|
if(items[i].links.hasOwnProperty('main')){
|
||||||
namefield = `<a href=${sl_items[i].links.main} target='_blank'>${sl_items[i].item_name}</a>`
|
namefield = `<a href=${item.links.main} target='_blank'>${item.item_name}</a>`
|
||||||
}
|
}
|
||||||
|
|
||||||
let nameCell = document.createElement('td')
|
let nameCell = document.createElement('td')
|
||||||
nameCell.innerHTML = namefield
|
nameCell.innerHTML = namefield
|
||||||
|
|
||||||
let qtyuomCell = document.createElement('td')
|
let qtyuomCell = document.createElement('td')
|
||||||
qtyuomCell.innerHTML = `${sl_items[i].qty} ${sl_items[i].uom.fullname}`
|
qtyuomCell.innerHTML = `${item.qty} ${item.uom.fullname}`
|
||||||
|
|
||||||
checkboxCell.checked = sl_items[i].list_item_state
|
checkboxCell.checked = item.list_item_state
|
||||||
tableRow.append(checkboxCell, nameCell, qtyuomCell)
|
tableRow.append(checkboxCell, nameCell, qtyuomCell)
|
||||||
listItemsTableBody.append(tableRow)
|
listItemsTableBody.append(tableRow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchShoppingList() {
|
async function fetchShoppingList() {
|
||||||
|
|||||||
@ -176,11 +176,11 @@
|
|||||||
<li class="uk-nav-header">Active Operators</li>
|
<li class="uk-nav-header">Active Operators</li>
|
||||||
<li class="uk-nav-divider"></li>
|
<li class="uk-nav-divider"></li>
|
||||||
<li><a onclick="addCustomItemsCard()" uk-tooltip="title: Create Custom items to add into the generated list.; pos: right">Custom Items</a></li>
|
<li><a onclick="addCustomItemsCard()" uk-tooltip="title: Create Custom items to add into the generated list.; pos: right">Custom Items</a></li>
|
||||||
<li><a onclick="addUncalculatedItemsCard()" uk-tooltip="title: Add items from the system that take a static quantity into the generated list.; pos: right">Non-Calculated System Items</a></li>
|
<li><a onclick="addUncalculatedItemsCard()" uk-tooltip="title: Add items from the system that take a static quantity into the generated list.; pos: right">Un-Calculated System Items</a></li>
|
||||||
<li><a onclick="addCalculatedItemsCard()" uk-tooltip="title: Add items from the system that calculate quantity using quantity on hand and a set safety stocks into the generated list.; pos: right">Calculated System Items</a></li>
|
<li><a onclick="addCalculatedItemsCard()" uk-tooltip="title: Add items from the system that calculate quantity using quantity on hand and a set safety stocks into the generated list.; pos: right">Calculated System Items</a></li>
|
||||||
<li><a onclick="addRecipesCard()" uk-tooltip="title: Add Recipes that will take all the ingrediants and add them into the generated list.; pos: right">System Recipes</a></li>
|
<li><a onclick="addRecipesCard()" uk-tooltip="title: Add Recipes that will take all the ingrediants and add them into the generated list.; pos: right">System Recipes</a></li>
|
||||||
<li><a onclick="addFullSKUCard()" uk-tooltip="title: Takes a full safety stock count from the system and adds any quantities below their safety stocks into the generated list.; pos: right">Full System Calculated</a></li>
|
<li><a onclick="addFullSKUCard()" uk-tooltip="title: Takes a full safety stock count from the system and adds any quantities below their safety stocks into the generated list.; pos: right">Full System Calculated</a></li>
|
||||||
<li><a class="uk-disabled" uk-tooltip="title: Uses a date range and selected planners for each to add any planned recipes into the generated list.; pos: right">Site Planners</a></li>
|
<li><a onclick="addPlannerCard()" uk-tooltip="title: Uses a date range and selected planners for each to add any planned recipes into the generated list.; pos: right">Site Planners</a></li>
|
||||||
<li><a onclick="addListsCard()" uk-tooltip="title: Combine already made lists into this one; pos: right">Shopping Lists</a></li>
|
<li><a onclick="addListsCard()" uk-tooltip="title: Combine already made lists into this one; pos: right">Shopping Lists</a></li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
@ -353,6 +353,39 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Full Calculated SKU -->
|
||||||
|
<div id="plannerCard" hidden>
|
||||||
|
<div class="uk-card uk-card-default uk-card-small uk-card-body">
|
||||||
|
<h3>Site Planner Operator
|
||||||
|
<span class="">
|
||||||
|
<button onclick="changePlannerZoneState()" class="uk-button uk-button-small" title="Show/Hide the card body." uk-tooltip>Show/Hide</button>
|
||||||
|
</span>
|
||||||
|
<span class="uk-align-right">
|
||||||
|
<button onclick="removePlannerCard()" class="uk-button uk-button-small" title="Will remove the Recipes card and data from the list." uk-tooltip >Remove</button>
|
||||||
|
</span>
|
||||||
|
</h3>
|
||||||
|
<p class="uk-text-meta">Site Planner Operators allow you to select specific plans and a date range on that planner to insert any planned recipes into the list. This is best
|
||||||
|
utilized without the Recipe Operator, but it has been allowed to have both. Currently you can only have one date range for a plan. If you
|
||||||
|
do attempt to add from the same plan twice it will overwrite the last date range.
|
||||||
|
</p>
|
||||||
|
<div id="plannerZone" uk-grid>
|
||||||
|
<div class="uk-width-1-1">
|
||||||
|
<table class="uk-table uk-table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Plan Name</th>
|
||||||
|
<th>Start Date</th>
|
||||||
|
<th>End Date</th>
|
||||||
|
<th>Operations</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="plannerTableBody"></tbody>
|
||||||
|
</table>
|
||||||
|
<button onclick="openPlannerModal()" class="uk-button uk-button-secondary uk-width-1-1">Add Item</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -655,6 +688,45 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Site Planner Modal -->
|
||||||
|
<div id="plannerModal" class="uk-modal">
|
||||||
|
<div class="uk-modal-dialog uk-modal-body">
|
||||||
|
<h2 class="uk-modal-title">Add Planner Date Range...</h2>
|
||||||
|
<p class="uk-text-small">Site Planner Operators allow you to select specific plans and a date range on that planner to insert any planned recipes into the list. This is best
|
||||||
|
utilized without the Recipe Operator, but it has been allowed to have both.
|
||||||
|
</p>
|
||||||
|
<table class="uk-table uk-table-responsive uk-table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Plan</td>
|
||||||
|
<td>
|
||||||
|
<select id="planUUID" class="uk-select" aria-label="Select">
|
||||||
|
<option value="site">Site Planner</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Start Date</td>
|
||||||
|
<td><input id="planStartDate" class="uk-input" type="date"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>End Date</td>
|
||||||
|
<td><input id="planEndDate" class="uk-input" type="date"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p class="uk-text-right">
|
||||||
|
<button class="uk-button uk-button-default uk-modal-close" type="button">Cancel</button>
|
||||||
|
<button id="plannerModalButton" onclick="addPlanner()" class="uk-button uk-button-primary" type="button">Add Planner</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -578,3 +578,27 @@
|
|||||||
2025-08-19 15:45:32.184317 --- ERROR --- DatabaseError(message='syntax error at or near "FROM"LINE 11: FROM main_items items ^',
|
2025-08-19 15:45:32.184317 --- ERROR --- DatabaseError(message='syntax error at or near "FROM"LINE 11: FROM main_items items ^',
|
||||||
payload={'item_uuid': '392f05b5-4ccd-41da-875d-0e593f51b610'},
|
payload={'item_uuid': '392f05b5-4ccd-41da-875d-0e593f51b610'},
|
||||||
sql='WITH sum_cte AS ( SELECT mi.id, SUM(mil.quantity_on_hand) AS total_sum FROM main_item_locations mil JOIN main_items mi ON mil.part_id = mi.id GROUP BY mi.id)SELECT items.*, COALESCE(row_to_json(item_info.*), '{}') AS item_info, COALESCE(sum_cte.total_sum, 0) AS total_sum,FROM main_items itemsLEFT JOIN main_item_info item_info ON items.item_info_id = item_info.idLEFT JOIN units ON units.id = item_info.uomLEFT JOIN sum_cte ON items.id = sum_cte.idWHERE items.item_uuid = %(item_uuid)s')
|
sql='WITH sum_cte AS ( SELECT mi.id, SUM(mil.quantity_on_hand) AS total_sum FROM main_item_locations mil JOIN main_items mi ON mil.part_id = mi.id GROUP BY mi.id)SELECT items.*, COALESCE(row_to_json(item_info.*), '{}') AS item_info, COALESCE(sum_cte.total_sum, 0) AS total_sum,FROM main_items itemsLEFT JOIN main_item_info item_info ON items.item_info_id = item_info.idLEFT JOIN units ON units.id = item_info.uomLEFT JOIN sum_cte ON items.id = sum_cte.idWHERE items.item_uuid = %(item_uuid)s')
|
||||||
|
2025-08-19 17:38:27.622014 --- ERROR --- DatabaseError(message='syntax error at or near ")"LINE 1: ...WHERE main_shopping_list_items.list_item_uuid IN () RETURNIN... ^',
|
||||||
|
payload=[],
|
||||||
|
sql='WITH deleted_rows AS (DELETE FROM main_shopping_list_items WHERE main_shopping_list_items.list_item_uuid IN () RETURNING *) SELECT * FROM deleted_rows;')
|
||||||
|
2025-08-19 17:39:39.750553 --- ERROR --- DatabaseError(message='syntax error at or near ")"LINE 1: ...WHERE main_shopping_list_items.list_item_uuid IN () RETURNIN... ^',
|
||||||
|
payload=[],
|
||||||
|
sql='WITH deleted_rows AS (DELETE FROM main_shopping_list_items WHERE main_shopping_list_items.list_item_uuid IN () RETURNING *) SELECT * FROM deleted_rows;')
|
||||||
|
2025-08-19 17:55:16.825854 --- ERROR --- DatabaseError(message='duplicate key value violates unique constraint "main_shopping_lists_name_key"DETAIL: Key (name)=() already exists.',
|
||||||
|
payload=('', '', 1, datetime.datetime(2025, 8, 19, 17, 55, 16, 816288), 'plain', 'temporary'),
|
||||||
|
sql='INSERT INTO main_shopping_lists(name, description, author, creation_date, sub_type, list_type) VALUES (%s, %s, %s, %s, %s, %s) RETURNING *;')
|
||||||
|
2025-08-20 05:17:43.764499 --- ERROR --- DatabaseError(message='syntax error at or near ")"LINE 1: ...WHERE main_shopping_list_items.list_item_uuid IN () RETURNIN... ^',
|
||||||
|
payload=[],
|
||||||
|
sql='WITH deleted_rows AS (DELETE FROM main_shopping_list_items WHERE main_shopping_list_items.list_item_uuid IN () RETURNING *) SELECT * FROM deleted_rows;')
|
||||||
|
2025-08-20 05:17:54.498269 --- ERROR --- DatabaseError(message='syntax error at or near ")"LINE 1: ...WHERE main_shopping_list_items.list_item_uuid IN () RETURNIN... ^',
|
||||||
|
payload=[],
|
||||||
|
sql='WITH deleted_rows AS (DELETE FROM main_shopping_list_items WHERE main_shopping_list_items.list_item_uuid IN () RETURNING *) SELECT * FROM deleted_rows;')
|
||||||
|
2025-08-20 05:17:57.313016 --- ERROR --- DatabaseError(message='syntax error at or near ")"LINE 1: ...WHERE main_shopping_list_items.list_item_uuid IN () RETURNIN... ^',
|
||||||
|
payload=[],
|
||||||
|
sql='WITH deleted_rows AS (DELETE FROM main_shopping_list_items WHERE main_shopping_list_items.list_item_uuid IN () RETURNING *) SELECT * FROM deleted_rows;')
|
||||||
|
2025-08-20 15:32:51.822870 --- ERROR --- DatabaseError(message='duplicate key value violates unique constraint "main_shopping_lists_name_key"DETAIL: Key (name)=(test) already exists.',
|
||||||
|
payload=('test', 'test', 1, datetime.datetime(2025, 8, 20, 15, 32, 51, 814595), 'plain', 'temporary'),
|
||||||
|
sql='INSERT INTO main_shopping_lists(name, description, author, creation_date, sub_type, list_type) VALUES (%s, %s, %s, %s, %s, %s) RETURNING *;')
|
||||||
|
2025-08-20 15:38:30.303845 --- ERROR --- DatabaseError(message='column "start_date" does not existLINE 1: ... FROM main_plan_events WHERE plan_uuid = NULL AND start_date... ^',
|
||||||
|
payload={'start_date': '2025-08-18', 'end_date': '2025-08-24', 'plan_uuid': None, 'plan_name': 'Site Planner'},
|
||||||
|
sql='SELECT * FROM main_plan_events WHERE plan_uuid = %(plan_uuid)s AND start_date <= %(end_date)s AND end_date >= %(start_date)s;')
|
||||||
Loading…
x
Reference in New Issue
Block a user