我正在使用 Quarkus、Hibernate、MSSQL 和 OptaPlanner 开发一个简单的仓库管理系统。当我点击“解决”按钮时,我希望将客户订单分配给库存位置。当我的系统解决(使用约束)时,StockLocationID 将针对 ShopifyOrders,例如 CustomerOrder1(PK) 将分配给 StockLocationID(FK) = 26。
它已在数据库中成功更新,但是数据应该被检索回来并反映到我的用户界面上,我不确定为什么。我一直在使用 quarkus-school-timetabling 示例(OptaPlanner),现在遇到了这个问题,它没有反映从我的数据库到我的 UI 的更改。
这可能是我的 JavaScript 文件的问题吗?如果我使用演示数据,它工作得很好,但由于我使用自己的数据库,它不起作用。
这是我当前的 javascript 文件:
function refreshAllDetails() {
$.getJSON("/allDetails", function (allDetails) {
refreshSolvingButtons(allDetails.solverStatus != null && allDetails.solverStatus !== "NOT_SOLVING");
$("#score").text("Score: " + (allDetails.score == null ? "?" : allDetails.score));
const allDetailsByRoom = $("#allDetailsByRoom");
allDetailsByRoom.children().remove();
const allDetailsByProductSKU = $("#allDetailsByProductSKU");
allDetailsByProductSKU.children().remove();
const allDetailsByProductName = $("#allDetailsByProductName");
allDetailsByProductName.children().remove();
const unassignedShopify = $("#unassignedShopify");
unassignedShopify.children().remove();
const theadByRoom = $("<thead>").appendTo(allDetailsByRoom);
const headerRowByRoom = $("<tr>").appendTo(theadByRoom);
headerRowByRoom.append($("<th>Picking Station</th>"));
$.each(allDetails.roomList, (index, room) => {
headerRowByRoom
.append($("<th/>")
.append($("<span/>").text(room.name))
.append($(`<button type="button" class="ml-2 mb-1 btn btn-light btn-sm p-1"/>`)
// .append($(`<small class="fas fa-trash"/>`)
.click(() => deleteRoom(room))));
});
const theadByProductSKU = $("<thead>").appendTo(allDetailsByProductSKU);
const headerRowByProductSKU = $("<tr>").appendTo(theadByProductSKU);
headerRowByProductSKU.append($("<th>Stock Location</th>"));
const productSKUList = [...new Set(allDetails.shopifyList.map(shopify => shopify.productSKU ))];
$.each(productSKUList, (index, productSKU) => {
headerRowByProductSKU
.append($("<th/>")
.append($("<span/>").text(productSKU)));
});
const theadByProductName = $("<thead>").appendTo(allDetailsByProductName);
const headerRowByProductName = $("<tr>").appendTo(theadByProductName);
headerRowByProductName.append($("<th>Stock Location</th>"));
const productNameList = [...new Set(allDetails.shopifyList.map(shopify => shopify.productName))];
$.each(productNameList, (index, productName) => {
headerRowByProductName
.append($("<th/>")
.append($("<span/>").text(productName)));
});
//Chnage productSKU to stockLocation
const tbodyByRoom = $("<tbody>").appendTo(allDetailsByRoom);
const tbodyByProductSKU = $("<tbody>").appendTo(allDetailsByProductSKU);
const tbodyByProductName = $("<tbody>").appendTo(allDetailsByProductName);
$.each(allDetails.stockLocationList, (index, stockLocation) => {
const rowByRoom = $("<tr>").appendTo(tbodyByRoom);
rowByRoom
.append($(`<th class="align-middle"/>`)
.append($("<span/>").text(`${stockLocation.stockLocation }`)
.append($("<br><em>").text(`SKU: ${stockLocation.productSKU}`)
.append($(`<button type="button" class="ml-2 mb-1 btn btn-light btn-sm p-1"/>`)))));
// .append($(`<small class="fas fa-trash"/>`)
// .click(() => deleteStockLocation(stockLocation))))));
const rowByProductSKU = $("<tr>").appendTo(tbodyByProductSKU);
rowByProductSKU
.append($(`<th class="align-middle"/>`)
.append($("<span/>").text(`
${stockLocation.productSKU}
`)));
$.each(allDetails.roomList, (index, room) => {
rowByRoom.append($("<td/>").prop("id", `stockLocation${stockLocation.id}room${room.id}`));
});
const rowByProductName = $("<tr>").appendTo(tbodyByProductName);
rowByProductName
.append($(`<th class="align-middle"/>`)
.append($("<span/>").text(`
${stockLocation.tower}
`)));
$.each(productSKUList, (index, productSKU) => {
rowByProductSKU.append($("<td/>").prop("id", `stockLocation${stockLocation.id}productSKU${convertToId(productSKU)}`));
});
$.each(productNameList, (index, productName) => {
rowByProductName.append($("<td/>").prop("id", `stockLocation${stockLocation.id}productName${convertToId(productName)}`));
});
});
$.each(allDetails.shopifyList, (index, shopify) => {
const color = pickColor(shopify.productSKU);
const lessonElementWithoutDelete = $(`<div class="card lesson" style="background-color: ${color}"/>`)
.append($(`<div class="card-body p-2"/>`)
.append($(`<h5 class="card-title mb-1"/>`).text(shopify.customerName))
.append($(`<p class="card-text ml-2 mb-1"/>`)
.append($(`<p class="card-text ml-2"/>`).text(`SKU: ${shopify.productSKU}`)
.append($(`<small class="ml-2 mt-1 card-text text-muted align-bottom float-right"/>`).text(shopify.shopifyID))
.append($(`<br><em>`).text(`Name: ${shopify.productName}`)))));
const lessonElement = lessonElementWithoutDelete.clone();
lessonElement.find(".card-body");
//$(`<button type="button" class="ml-2 btn btn-light btn-sm p-1 float-right"/>`)
//.append($(`<small class="fas fa-trash"/>`)
//.click(() => deleteShopify(shopify)
if (shopify.stockLocation == null || shopify.room == null) {
unassignedShopify.append(lessonElement);
} else {
$(`#stockLocation${shopify.stockLocation.id}room${shopify.room.id}`).append(lessonElement);
$(`#stockLocation${shopify.stockLocation.id}productSKU${convertToId(shopify.productSKU)}`).append(lessonElementWithoutDelete.clone());
$(`#stockLocation${shopify.stockLocation.id}productName${convertToId(shopify.productName)}`).append(lessonElementWithoutDelete.clone());
}
});
});
}
function convertToId(str) {
// Base64 encoding without padding to avoid XSS
return btoa(str).replace(/=/g, "");
}
function solve() {
$.post("/allDetails/solve", function () {
refreshSolvingButtons(true);
}).fail(function (xhr, ajaxOptions, thrownError) {
showError("Start solving failed.", xhr);
});
}
function refreshSolvingButtons(solving) {
if (solving) {
$("#solveButton").hide();
$("#stopSolvingButton").show();
if (autoRefreshIntervalId == null) {
autoRefreshIntervalId = setInterval(refreshAllDetails, 2000);
}
} else {
$("#solveButton").show();
$("#stopSolvingButton").hide();
if (autoRefreshIntervalId != null) {
clearInterval(autoRefreshIntervalId);
autoRefreshIntervalId = null;
}
}
}
function stopSolving() {
$.post("/allDetails/stopSolving", function () {
refreshSolvingButtons(false);
refreshAllDetails();
}).fail(function (xhr, ajaxOptions, thrownError) {
showError("Stop solving failed.", xhr);
});
}
function showError(title, xhr) {
const serverErrorMessage = !xhr.responseJSON ? `${xhr.status}: ${xhr.statusText}` : xhr.responseJSON.message;
console.error(title + "\n" + serverErrorMessage);
const notification = $(`<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" style="min-width: 30rem"/>`)
.append($(`<div class="toast-header bg-danger">
<strong class="mr-auto text-dark">Error</strong>
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>`))
.append($(`<div class="toast-body"/>`)
.append($(`<p/>`).text(title))
.append($(`<pre/>`)
.append($(`<code/>`).text(serverErrorMessage))
)
);
$("#notificationPanel").append(notification);
notification.toast({delay: 30000});
notification.toast('show');
}
$(document).ready(function () {
$.ajaxSetup({
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
;
// Extend jQuery to support $.put() and $.delete()
jQuery.each(["put", "delete"], function (i, method) {
jQuery[method] = function (url, data, callback, type) {
if (jQuery.isFunction(data)) {
type = type || callback;
callback = data;
data = undefined;
}
return jQuery.ajax({
url: url,
type: method,
dataType: type,
data: data,
success: callback
})
};
});
$("#refreshButton").click(function () {
refreshAllDetails();
});
$("#solveButton").click(function () {
solve();
});
$("#stopSolvingButton").click(function () {
stopSolving();
});
refreshAllDetails();
});
它与我的 JavaScript 文件中的这个函数有什么特别的关系吗?
$(document).ready(function () {
$.ajaxSetup({
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
;
// Extend jQuery to support $.put() and $.delete()
jQuery.each(["put", "delete"], function (i, method) {
jQuery[method] = function (url, data, callback, type) {
if (jQuery.isFunction(data)) {
type = type || callback;
callback = data;
data = undefined;
}
return jQuery.ajax({
url: url,
type: method,
dataType: type,
data: data,
success: callback
})
};
});
您可能想看看https://www.tsql.app。
这是一个您可以使用的基于数据驱动的 SQLSERVER 的 Web 应用程序框架。它有一个内置 IDE,还用于构建仓库管理系统 (https://wms.tsql.app) 以及其他 ERP 解决方案。
所有自定义代码都是纯 SQL,即使是 UI,例如:(荷兰语评论)
--------------------------------------------------------------------------------
-- action: create_micro_outbound
-- card: wms_out_transport
-- pre declare:
/*
@klant, @Opdrachtgever, @destLoc,@transporteur, @button,@DestCode, @ContainerID, @RekenPallets int
,@Outboundreleasenumber, @Outbounddate,@ContainerNR,@verschil int, @ContainerFilter,@ffa,@reduc,@choose_value,@PalletIDS,@selIDS,@outbound_method,@select_all,@b_in,@warehouse_instructions,@newdestButton, @code, @cname,@caddr,@ndsave,@isnew,@license_plate
*/
-- 220415 uitgebreid met customs_state
-- 221011 kopie van outbound, maar aangepast voor items.
--------------------------------------------------------------------------------
set @transporteur=(select top 1 id from xcompany where code like 'blan%')
set @destloc=(select id from xlocation where locationcode='onbekend')
exec sp_api_modal_text N'Transporteur'
EXEC sp_api_modal_select @card_name = N'transporteur',@value = @transporteur OUT, @initial_id=@transporteur -- ,@focus = 1
--ffa
exec #ffa_met_micro_stock @ffa_id=@ffa OUT
if @ffa is null
begin
exec sp_api_modal_text N'U moet de FFA opgeven, want u krijgt alleen containers van de klant en deze FFA te zien.'
return;
end
--client
exec #klant_van_ffa_met_micro_stock @ffa_id=@ffa, @klant_id=@opdrachtgever OUT
--WAREHOUSE INSTELLEN.. VALT NU TERUG VIA API CONFIG SETTINGS (select warehouse_id from micro_outbound_warehouse(ffa_id)
exec sp_api_modal_text N'Warehouse'
SELECT id=Id,name=CONCAT(locationCode,'') INTO #wh FROM xLocation where company_id in (select id from xtenantkey)
EXEC sp_api_modal_select_table N'#wh',@value = @warehouse_id OUT,@focus = 0,@placeholder=N'Kies het warehouse',@no_isam=1
exec sp_api_modal_text N'pick-up lokatie'
SELECT id=Id,name=position_code INTO #pl FROM wms_pickup_location
EXEC sp_api_modal_select_table N'#pl',@value = @pickup_location_id OUT,@focus = 0,@placeholder=N'Kies de pickup lokatie of laat leeg',@no_isam=1
--@Outboundreleasenumber
exec sp_api_modal_text N'Opdrachtnummer' --REF IN TRANSPORT !!
EXEC sp_api_modal_input @name='Naam',@max=30, @value= @Outboundreleasenumber OUT ,@placeholder='Opdrachtnummer'--,@focus=1,@select=1
--if nullif(trim(@Outboundreleasenumber),N'') is null RETURN -- 230823 VERPLICHT GEMAAKT
--230615
exec sp_api_modal_text N'License plate / truck id'
EXEC sp_api_modal_input @name='license plate',@max=30, @value= @license_plate OUT ,@placeholder='license_plate'--,@focus=1,@select=1
exec sp_api_modal_text N'Transportdatum'
set @Outbounddate=dbo.Workdate()
EXEC sp_api_modal_date @name='Datum', @value= @Outbounddate OUT,@focus=0
--EXEC sp_api_modal_input @name='Naam',@max=5, @value= @Outboundreleasenumber OUT --,@focus=1,@select=1
--@Outboundreleasenumber
exec sp_api_modal_text N'Warehouse Instructions'
EXEC sp_api_modal_input @name='instructions',@max=60, @value= @warehouse_instructions OUT ,@placeholder='Instructions'--,@focus=1,@select=1
--230614
--extra predeclare: ,@newdestButton, @code, @cname,@caddr,@ndsave,@isnew
EXEC sp_api_modal_button @name='@newdestbutton',@value = 'Maak nieuwe bestemming', @valueout = @newdestbutton OUT,@class='btn-danger',@key='F3'
if @newdestbutton is not NULL
BEGIN
EXEC sp_api_modal_text 'code',N'h2'
EXEC sp_api_modal_input @name = '@code', @value = @code OUT --,@inline = 1
EXEC sp_api_modal_text 'bedrijfsnaam (bestemming)',N'h2'
EXEC sp_api_modal_input @name = '@cname', @value = @cname OUT --,@inline = 1
EXEC sp_api_modal_text 'Volledig adres',N'h2'
EXEC sp_api_modal_input @name='@caddr',@value= @caddr OUT,@type='textarea',@placeholder='Compleet adres',@rows=6,@select=0
EXEC sp_api_modal_button @name='@ndsave',@value = 'Nieuwe bestemming opslaan', @valueout = @ndsave OUT,@class='btn-danger',@key='F5'
if @ndsave is not null
and @cname is not null
and @caddr is not null
and @code is not NULL
begin
if not exists(select * from xcompany where code=@code)
begin
set @isnew=1
exec sp_api_toast N'NIEUWE BESTEMMING TOEGEVOEGD'
insert into xcompany(companyname, completeAddress, code,is_wms_outbound_destination)
values(@cname,@caddr,@code,1)
set @destloc=(select id from xcompany where code=@code)
end
ELSE
BEGIN
if @isnew =1 --alleen als het net is aangemaakt mag het adres wijzigen!!
begin
exec sp_api_toast N'wijzig addr'
--adres van nieuwe code mag evt nog wijzigen
update xcompany set completeAddress=@caddr where code=@code and is_wms_outbound_destination=1
end
END
end
END
exec sp_api_modal_text N'Bestemming'
--EXEC sp_api_modal_select @card_name = N'loc',@value = @destloc OUT, @initial_id=@destloc,@reducer=' company_id in (select id from xcompany where is_wms_outbound_destination=1)'
--230607 volledig adres er bij
SELECT id=Id,name=CONCAT(locationCode,': ',completeAddress) INTO #loca FROM xLocation where company_id in (select id from xcompany where is_wms_outbound_destination=1)
EXEC sp_api_modal_select_table N'#loca',@value = @destloc OUT,@focus = 0,@placeholder=N'Kies een locatie', @initial_id=@destloc,@no_isam=1
EXEC sp_api_modal_button @name='@b_in',@value = 'Opslaan (F8)', @valueout = @button OUT,@class='btn-danger',@key='F8'
if @b_in =N'Opslaan (F8)'
begin
insert into wms_micro_outbound(
[date]
,[ffa_id]
,[status]
,[customer_id]
,[to_loc_id]
,[out_ref]
,[container]
,[transporter_id]
,[transport_ID]
,[warehouse_instructions]
,[expected_license_plate] --let op, de uiteindelijke heet: LicensePlate in xTransport
,warehouse_id --230822
,wms_pickup_location_id --231122
)
values(
@Outbounddate
,@ffa
,'New'
,@opdrachtgever
,@destloc
,@Outboundreleasenumber
,NULL -- container nr ..
,@transporteur
,NULL
,@warehouse_instructions
,@license_plate
,@warehouse_id --230822
,@pickup_location_id --231122
)
--221203 ga naar het nieuwe record in de lijst
declare @newID int =scope_Identity()
if @newID >0
begin
declare @gt nvarchar(256)=concat(@path,'?id=',@newid)
exec sp_api_goto @path=@gt
end
exec sp_api_modal_clear;
end
return;