diff options
author | rtk0c <[email protected]> | 2021-05-08 21:10:36 -0700 |
---|---|---|
committer | rtk0c <[email protected]> | 2021-05-08 21:10:36 -0700 |
commit | 850067a6db2443c1ff1ced793135796ef7ac490f (patch) | |
tree | ddef664def68b9868d2d04655654cd9854c5d825 /core/src/UI | |
parent | 1fd1e4b5f2418e3ac2909658993bfedb615537ec (diff) |
Deliveries table working, item column
Diffstat (limited to 'core/src/UI')
-rw-r--r-- | core/src/UI/Localization.hpp | 13 | ||||
-rw-r--r-- | core/src/UI/UI_DatabaseView.cpp | 212 |
2 files changed, 175 insertions, 50 deletions
diff --git a/core/src/UI/Localization.hpp b/core/src/UI/Localization.hpp index 043170a..46cf740 100644 --- a/core/src/UI/Localization.hpp +++ b/core/src/UI/Localization.hpp @@ -64,13 +64,22 @@ public: BasicTranslation PurchasesViewTab{ "Database.PurchasesView.TabName"sv }; BasicTranslation EditPurchaseEntryDialogTitle{ "Database.PurchasesView.Edit.DialogTitle"sv }; + BasicTranslation DatabaseItemsColumn{ "Database.Column.Items"sv }; BasicTranslation DatabaseCustomerColumn{ "Database.Column.Customer"sv }; BasicTranslation DatabaseFactoryColumn{ "Database.Column.Factory"sv }; + /// 销售订单的交货期限 BasicTranslation DatabaseDeadlineColumn{ "Database.Column.Deadline"sv }; + /// 采购订单的下单时间 BasicTranslation DatabaseOrderTimeColumn{ "Database.Column.OrderTime"sv }; - BasicTranslation DatabaseDeliveryTimeColumn{ "Database.Column.DeliveryTime"sv }; + /// 所有订单的“完成”时间。对于销售来说是实际交货时间,对于采购来说是收货时间。 + BasicTranslation DatabaseCompletionTimeColumn{ "Database.Column.CompletionTime"sv }; + /// (运输)批次的发货时间,适用于采购和销售批次。 + BasicTranslation DatabaseShipmentTimeColumn{ "Database.Column.ShipmentTime"sv }; + /// (运输)批次的收获时间,适用于采购和销售批次。 + BasicTranslation DatabaseArrivalTimeColumn{ "Database.Column.ArrivalTime"sv }; - BasicTranslation NotDelievered{ "Database.Message.NotDelivered"sv }; + BasicTranslation SelectOrderToShowAssociatedDeliveries{ "Database.Message.NoOrderSelected"sv }; + BasicTranslation NotDelivered{ "Database.Message.NotDelivered"sv }; /* Items tab */ diff --git a/core/src/UI/UI_DatabaseView.cpp b/core/src/UI/UI_DatabaseView.cpp index bc458da..b9d9d81 100644 --- a/core/src/UI/UI_DatabaseView.cpp +++ b/core/src/UI/UI_DatabaseView.cpp @@ -20,6 +20,8 @@ namespace { // TODO move to Settings constexpr int kMaxEntriesPerPage = 20; +constexpr int kSummaryItemCount = 3; +constexpr int kSummaryMaxLength = 25; enum class DeliveryDirection { @@ -27,8 +29,16 @@ enum class DeliveryDirection WarehouseToCustomer, }; +struct ItemEntry +{ + int ItemId; + int Count; +}; + struct DeliveryEntry { + std::vector<ItemEntry> Items; + std::string ItemsSummary; std::string ShipmentTime; std::string ArriveTime; DeliveryDirection Direction; @@ -129,14 +139,13 @@ public: virtual void OnFilterChanged() { auto& stmt = *mFilterRowsStatement; - DEFER - { - stmt.reset(); - }; + // clang-format off + DEFER { stmt.reset(); }; + // clang-format on // TODO lazy loading when too many results mActiveEntries.clear(); - int columnIdx = stmt.getColumnIndex("rowid"); + int columnIdx = stmt.getColumnIndex("Id"); while (stmt.executeStep()) { mActiveEntries.push_back(stmt.getColumn(columnIdx).getInt()); } @@ -187,19 +196,29 @@ public: // TODO } - if (mSelectedEntryRowId == -1) { - DrawMainTable(); - } else { - // TODO better layout + ImGui::SameLine(); + if (ImGui::Button(ls->Delete.Get(), mSelectedEntryRowId == -1)) { + // TODO + } + + ImGui::Columns(2); + { DrawMainTable(); - ImGui::SameLine(); - DrawDeliveriesTable(); + ImGui::NextColumn(); + + if (mSelectedEntryRowId == -1) { + ImGui::TextWrapped("%s", ls->SelectOrderToShowAssociatedDeliveries.Get()); + } else { + DrawDeliveriesTable(); + } + ImGui::NextColumn(); } + ImGui::Columns(1); } void DrawMainTable() { - if (ImGui::BeginTable("DataTable", GetTableColumnCount(), ImGuiTableFlags_ScrollX)) { + if (ImGui::BeginTable("DataTable", GetTableColumnCount(), ImGuiTableFlags_Borders | ImGuiTableFlags_ScrollX)) { SetupTableColumns(); ImGui::TableHeadersRow(); @@ -223,10 +242,12 @@ public: void DrawDeliveriesTable() { - if (ImGui::BeginTable("DeliveriesTable", 2)) { + auto ls = LocaleStrings::Instance.get(); + if (ImGui::BeginTable("DeliveriesTable", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_ScrollX)) { - ImGui::TableSetupColumn("Shipment time"); - ImGui::TableSetupColumn("Arrival time"); + ImGui::TableSetupColumn(ls->DatabaseShipmentTimeColumn.Get()); + ImGui::TableSetupColumn(ls->DatabaseArrivalTimeColumn.Get()); + ImGui::TableSetupColumn(ls->DatabaseItemsColumn.Get()); ImGui::TableHeadersRow(); auto& deliveries = GetEntryAssociatedDeliveries(mSelectedEntryRowId); @@ -238,6 +259,12 @@ public: ImGui::TableNextColumn(); ImGui::TextUnformatted(delivery.ArriveTime.c_str()); + + ImGui::TableNextColumn(); + if (ImGui::TreeNode(delivery.ItemsSummary.c_str())) { + DrawItems(delivery.Items); + ImGui::TreePop(); + } } ImGui::EndTable(); @@ -260,6 +287,53 @@ public: return index + mFirstCachedRowId; } + std::vector<ItemEntry> LoadItems(SQLite::Statement& stmt, int64_t rowId) + { + // clang-format off + DEFER { stmt.reset(); }; + // clang-format on + + stmt.bind(1, rowId); + + std::vector<ItemEntry> entries; + int itemIdCol = stmt.getColumnIndex("ItemId"); + int countCol = stmt.getColumnIndex("Count"); + while (stmt.executeStep()) { + entries.push_back(ItemEntry{ + .ItemId = stmt.getColumn(itemIdCol).getInt(), + .Count = stmt.getColumn(countCol).getInt(), + }); + } + + return entries; + } + + std::string CreateItemsSummary(const std::vector<ItemEntry>& items) + { + if (items.empty()) { + return "<empty>"; + } + + std::string result; + for (int i = 0, max = std::min((int)items.size(), kSummaryItemCount); i < max; ++i) { + auto& name = mProject->Products.Find(items[i].ItemId)->GetName(); + if (result.length() + name.length() > kSummaryMaxLength) { + break; + } + + result += name; + result += ", "; + } + + // Remove ", " + result.pop_back(); + result.pop_back(); + + result += "..."; + + return result; + } + std::vector<DeliveryEntry> LoadDeliveriesEntries(int64_t orderRowId, DeliveryDirection type) { bool outgoingFlag; @@ -269,19 +343,26 @@ public: } auto& stmt = mProject->GetTransactionsModel().GetDeliveries().FilterByTypeAndId; - DEFER - { - stmt.reset(); - }; + // clang-format off + DEFER { stmt.reset(); }; + // clang-format on stmt.bind(1, orderRowId); - stmt.bind(2, static_cast<int>(type)); + stmt.bind(2, outgoingFlag); std::vector<DeliveryEntry> entries; + int rowIdCol = stmt.getColumnIndex("Id"); int sendTimeCol = stmt.getColumnIndex("ShipmentTime"); int arrivalTimeCol = stmt.getColumnIndex("ArrivalTime"); while (stmt.executeStep()) { + auto items = LoadItems( + mProject->GetTransactionsModel().GetDeliveries().GetItems, + stmt.getColumn(rowIdCol).getInt64()); + auto summary = CreateItemsSummary(items); + entries.push_back(DeliveryEntry{ + .Items = std::move(items), + .ItemsSummary = std::move(summary), .ShipmentTime = StringifyTimeStamp(stmt.getColumn(arrivalTimeCol).getInt64()), .ArriveTime = StringifyTimeStamp(stmt.getColumn(sendTimeCol).getInt64()), .Direction = type, @@ -301,6 +382,14 @@ protected: virtual void ClearEntries() = 0; + void DrawItems(const std::vector<ItemEntry>& items) + { + for (auto& item : items) { + auto& name = mProject->Products.Find(item.ItemId)->GetName(); + ImGui::Text("%s × %d", name.c_str(), item.Count); + } + } + void EnsureCacheCoversPage(int page) { auto [begin, end] = CalcRangeForPage(page); @@ -360,10 +449,9 @@ protected: result.reserve(size); - DEFER - { - mGetRowsStatement->reset(); - }; + // clang-format off + DEFER { mGetRowsStatement->reset(); }; + // clang-format on mGetRowsStatement->bind(1, begin); mGetRowsStatement->bind(2, end); @@ -380,10 +468,11 @@ private: } }; -class SaleEntry +struct SaleEntry { -public: std::vector<DeliveryEntry> AssociatedDeliveries; + std::vector<ItemEntry> Items; + std::string ItemsSummary; std::string Customer; std::string Deadline; std::string DeliveryTime; @@ -416,7 +505,7 @@ public: protected: virtual int GetTableColumnCount() const override { - return 3; + return 4; } virtual void SetupTableColumns() override @@ -424,7 +513,8 @@ protected: auto ls = LocaleStrings::Instance.get(); ImGui::TableSetupColumn(ls->DatabaseCustomerColumn.Get()); ImGui::TableSetupColumn(ls->DatabaseDeadlineColumn.Get()); - ImGui::TableSetupColumn(ls->DatabaseDeliveryTimeColumn.Get()); + ImGui::TableSetupColumn(ls->DatabaseCompletionTimeColumn.Get()); + ImGui::TableSetupColumn(ls->DatabaseItemsColumn.Get()); } virtual const std::vector<DeliveryEntry>& GetEntryAssociatedDeliveries(int rowId) override @@ -455,17 +545,23 @@ protected: ImGui::TableNextColumn(); if (entry.DeliveryTime.empty()) { - ImGui::TextUnformatted(ls->NotDelievered.Get()); + ImGui::TextUnformatted(ls->NotDelivered.Get()); } else { ImGui::TextUnformatted(entry.DeliveryTime.c_str()); } + ImGui::TableNextColumn(); + if (ImGui::TreeNode(entry.ItemsSummary.c_str())) { + DrawItems(entry.Items); + ImGui::TreePop(); + } + ImGui::PopID(); } virtual void EditEntry(int rowId) override { - // `TODO` + // TODO } virtual void ClearEntries() override @@ -477,18 +573,24 @@ protected: { auto CollectRows = [&](std::vector<SaleEntry>& result) { auto& stmt = *mGetRowsStatement; + int rowIdCol = stmt.getColumnIndex("Id"); int customerCol = stmt.getColumnIndex("Customer"); int deadlineCol = stmt.getColumnIndex("Deadline"); int deliveryTimeCol = stmt.getColumnIndex("DeliveryTime"); while (stmt.executeStep()) { - auto customer = stmt.getColumn(customerCol).getInt(); - auto deadline = stmt.getColumn(deadlineCol).getInt64(); - auto deliveryTime = stmt.getColumn(deliveryTimeCol).getInt64(); + auto customerId = stmt.getColumn(customerCol).getInt(); + auto items = LoadItems( + mProject->GetTransactionsModel().GetSales().GetItems, + stmt.getColumn(rowIdCol).getInt64()); + auto itemsSummary = CreateItemsSummary(items); + result.push_back(SaleEntry{ - .Customer = mProject->Customers.Find(customer)->GetName(), - .Deadline = StringifyTimeStamp(deadline), - .DeliveryTime = StringifyTimeStamp(deliveryTime), + .Items = std::move(items), + .ItemsSummary = std::move(itemsSummary), + .Customer = mProject->Customers.Find(customerId)->GetName(), + .Deadline = StringifyTimeStamp(stmt.getColumn(deadlineCol).getInt64()), + .DeliveryTime = StringifyTimeStamp(stmt.getColumn(deliveryTimeCol).getInt64()), }); } }; @@ -497,10 +599,11 @@ protected: } }; -class PurchaseEntry +struct PurchaseEntry { -public: std::vector<DeliveryEntry> AssociatedDeliveries; + std::vector<ItemEntry> Items; + std::string ItemsSummary; std::string Factory; std::string OrderTime; std::string DeliveryTime; @@ -532,7 +635,7 @@ public: protected: virtual int GetTableColumnCount() const override { - return 3; + return 4; } virtual void SetupTableColumns() override @@ -540,7 +643,8 @@ protected: auto ls = LocaleStrings::Instance.get(); ImGui::TableSetupColumn(ls->DatabaseFactoryColumn.Get()); ImGui::TableSetupColumn(ls->DatabaseOrderTimeColumn.Get()); - ImGui::TableSetupColumn(ls->DatabaseDeliveryTimeColumn.Get()); + ImGui::TableSetupColumn(ls->DatabaseCompletionTimeColumn.Get()); + ImGui::TableSetupColumn(ls->DatabaseItemsColumn.Get()); } virtual const std::vector<DeliveryEntry>& GetEntryAssociatedDeliveries(int rowId) override @@ -568,18 +672,24 @@ protected: ImGui::TableNextColumn(); if (entry.OrderTime.empty()) { - ImGui::TextUnformatted(ls->NotDelievered.Get()); + ImGui::TextUnformatted(ls->NotDelivered.Get()); } else { ImGui::TextUnformatted(entry.OrderTime.c_str()); } ImGui::TableNextColumn(); if (entry.DeliveryTime.empty()) { - ImGui::TextUnformatted(ls->NotDelievered.Get()); + ImGui::TextUnformatted(ls->NotDelivered.Get()); } else { ImGui::TextUnformatted(entry.DeliveryTime.c_str()); } + ImGui::TableNextColumn(); + if (ImGui::TreeNode(entry.ItemsSummary.c_str())) { + DrawItems(entry.Items); + ImGui::TreePop(); + } + ImGui::PopID(); } @@ -597,18 +707,24 @@ protected: { auto CollectRows = [&](std::vector<PurchaseEntry>& result) { auto& stmt = *mGetRowsStatement; + int rowIdCol = stmt.getColumnIndex("Id"); int factoryCol = stmt.getColumnIndex("Factory"); int orderTimeCol = stmt.getColumnIndex("OrderTime"); int deliveryTimeCol = stmt.getColumnIndex("DeliveryTime"); while (stmt.executeStep()) { - auto factory = stmt.getColumn(factoryCol).getInt(); - auto orderTime = stmt.getColumn(orderTimeCol).getInt64(); - auto deliveryTime = stmt.getColumn(deliveryTimeCol).getInt64(); + auto factoryId = stmt.getColumn(factoryCol).getInt(); + auto items = LoadItems( + mProject->GetTransactionsModel().GetPurchases().GetItems, + stmt.getColumn(rowIdCol).getInt64()); + auto itemsSummary = CreateItemsSummary(items); + result.push_back(PurchaseEntry{ - .Factory = mProject->Factories.Find(factory)->GetName(), - .OrderTime = StringifyTimeStamp(orderTime), - .DeliveryTime = StringifyTimeStamp(deliveryTime), + .Items = std::move(items), + .ItemsSummary = std::move(itemsSummary), + .Factory = mProject->Factories.Find(factoryId)->GetName(), + .OrderTime = StringifyTimeStamp(stmt.getColumn(orderTimeCol).getInt64()), + .DeliveryTime = StringifyTimeStamp(stmt.getColumn(deliveryTimeCol).getInt64()), }); } }; |