From 555a753a6247fbaf4c9f7261ea1cbfacd2f76dec Mon Sep 17 00:00:00 2001 From: ModernWMS <119478674+ModernWMS@users.noreply.github.com> Date: Tue, 10 Jan 2023 14:55:03 +0800 Subject: [PATCH] Merge: Merge first commit from release to master (#2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * init * Merge: Merge first commit from develop to release (#1) * init * init * init * first commit * feat(全局): 增加hook组件, 用于对话框、消息提示; 修改系统标题 * feat(Global):Sync gitee code with frontend on 2023-01-09 09:14. * feat(Global):Remove 'sqls' file. * feat(Commodity management): Delete volume verification * feat(Delivery Management): Modify tab English * feat(Back End): Synchronize back-end code_2023-01-09 10:33 * feat(package.json):Fixed dependecies version. * feat(Global):Update the readme. * feat(Global):Fix the readme. Co-authored-by: lysddp Co-authored-by: liufu <809388027@qq.com> Co-authored-by: Jokerls波吉 <11269866+jokerls-poji@user.noreply.gitee.com> Co-authored-by: lysddp Co-authored-by: liufu <809388027@qq.com> Co-authored-by: Jokerls波吉 <11269866+jokerls-poji@user.noreply.gitee.com> --- .gitignore | 388 ++ README.md | 198 + .../Controller/AccountController.cs | 138 + .../Controller/BaseController.cs | 40 + .../ModernWMS.Core/DBContext/CallContext.cs | 30 + .../ModernWMS.Core/DBContext/SqlDBContext.cs | 128 + backend/ModernWMS.Core/DI/IDependency.cs | 7 + .../DynamicSearch/QueryCollection.cs | 120 + .../DynamicSearch/QueryOptions.cs | 71 + .../DynamicSearch/SearchObject.cs | 55 + .../Extentions/JsonStringTrimConverter.cs | 62 + .../Extentions/StartupExtensions.cs | 292 ++ .../ModernWMS.Core/JWT/ApiResponseHandler.cs | 85 + backend/ModernWMS.Core/JWT/CacheManger.cs | 152 + backend/ModernWMS.Core/JWT/ClaimValueTypes.cs | 13 + backend/ModernWMS.Core/JWT/CurrentUser.cs | 34 + backend/ModernWMS.Core/JWT/ITokenManager.cs | 36 + backend/ModernWMS.Core/JWT/TokenManager.cs | 182 + backend/ModernWMS.Core/JWT/TokenSettings.cs | 26 + .../Middleware/CorsMiddleware.cs | 61 + .../Middleware/GlobalExceptionMiddleware.cs | 105 + .../Middleware/RequestResponseMiddleware.cs | 138 + .../Middleware/ViewModelActionFiter.cs | 78 + backend/ModernWMS.Core/Models/BaseModel.cs | 16 + .../Models/BatchOperationViewModel.cs | 13 + .../ModernWMS.Core/Models/FormSelectItem.cs | 32 + .../Models/LoginInputViewModel.cs | 25 + .../Models/LoginOutputViewModel.cs | 57 + .../ModernWMS.Core/Models/MultiLanguage.cs | 12 + .../Models/MultiLanguage.en-us.resx | 636 +++ .../Models/MultiLanguage.zh-cn.resx | 636 +++ backend/ModernWMS.Core/Models/PageData.cs | 24 + backend/ModernWMS.Core/Models/PageSearch.cs | 30 + .../Models/RefreshTokenInPutViewModel.cs | 22 + backend/ModernWMS.Core/Models/ResultModel.cs | 51 + .../ModernWMS.Core/Models/UserroleEntity.cs | 52 + backend/ModernWMS.Core/Models/userEntity.cs | 83 + backend/ModernWMS.Core/ModernWMS.Core.csproj | 53 + .../MultiTenancy/ITenantProvider.cs | 14 + backend/ModernWMS.Core/MultiTenancy/Tenant.cs | 17 + .../MultiTenancy/TenantProvider.cs | 46 + .../ModernWMS.Core/Services/AccountService.cs | 78 + .../ModernWMS.Core/Services/BaseService.cs | 18 + .../Services/IAccountService.cs | 24 + .../ModernWMS.Core/Services/IBaseService.cs | 16 + .../Swagger/CustomApiVersion.cs | 25 + .../ModernWMS.Core/Swagger/SwaggerSettings.cs | 38 + backend/ModernWMS.Core/Swagger/index.html | 120 + .../ModernWMS.Core/Utility/GlobalConsts.cs | 31 + backend/ModernWMS.Core/Utility/JsonHelper.cs | 63 + backend/ModernWMS.Core/Utility/Md5Helper.cs | 32 + .../Utility/ModelConvertHelper.cs | 106 + backend/ModernWMS.Core/Utility/UtilConvert.cs | 285 ++ .../Controllers/Asn/AsnController.cs | 326 ++ .../Customer/CustomerController.cs | 179 + .../Dispatchlist/DispatchlistController.cs | 343 ++ .../Freightfee/FreightfeeController.cs | 182 + .../GoodsOwner/GoodsownerController.cs | 179 + .../Goodslocation/GoodslocationController.cs | 174 + .../Rolemenu/RolemenuController.cs | 181 + .../Controllers/Sku/CategoryController.cs | 147 + .../Controllers/Sku/SpuController.cs | 164 + .../Controllers/Stock/StockController.cs | 122 + .../Stockadjust/StockadjustController.cs | 72 + .../Stockfreeze/StockfreezeController.cs | 164 + .../Stockmove/StockmoveController.cs | 164 + .../Stockprocess/StockprocessController.cs | 201 + .../Stocktaking/StocktakingController.cs | 165 + .../Warehouse/WarehouseController.cs | 195 + .../Warehousearea/WarehouseareaController.cs | 174 + .../Controllers/company/CompanyController.cs | 142 + .../supplier/SupplierController.cs | 183 + .../Controllers/user/UserController.cs | 248 ++ .../userrole/UserroleController.cs | 163 + .../Entities/Models/Asn/AsnEntity.cs | 132 + .../Entities/Models/Asn/AsnsortEntity.cs | 59 + .../Models/Customer/CustomerEntity.cs | 69 + .../Models/Dispatchlist/DispatchlistEntity.cs | 183 + .../Dispatchlist/DispatchpicklistEntity.cs | 76 + .../Models/Freightfee/FreightfeeEntity.cs | 82 + .../Models/GoodsOwner/GoodsownerEntity.cs | 64 + .../Goodslocation/GoodslocationEntity.cs | 122 + .../Entities/Models/Rolemenu/MenuEntity.cs | 54 + .../Models/Rolemenu/RolemenuEntity.cs | 57 + .../Entities/Models/Sku/CategoryEntity.cs | 59 + .../Entities/Models/Sku/SkuEntity.cs | 100 + .../Entities/Models/Sku/SpuEntity.cs | 118 + .../Entities/Models/Stock/StockEntity.cs | 63 + .../Models/Stockadjust/StockadjustEntity.cs | 87 + .../Models/Stockfreeze/StockfreezeEntity.cs | 72 + .../Models/Stockmove/StockmoveEntity.cs | 92 + .../Models/Stockprocess/StockprocessEntity.cs | 82 + .../Stockprocess/StockprocessdetailEntity.cs | 79 + .../Models/Stocktaking/StocktakingEntity.cs | 96 + .../Models/Warehouse/WarehouseEntity.cs | 82 + .../Warehousearea/WarehouseareaEntity.cs | 67 + .../Entities/Models/company/CompanyEntity.cs | 52 + .../Models/supplier/SupplierEntity.cs | 82 + .../Asn/AsnBulkModifyGoodsOwnerViewModel.cs | 48 + .../Entities/ViewModels/Asn/AsnViewModel.cs | 218 ++ .../Asn/Flow/AsnFlowInputViewModel.cs | 36 + .../Asn/Flow/AsnPutAwayInputViewModel.cs | 48 + .../Asn/Flow/AsnsortInputViewModel.cs | 42 + .../Customer/CustomerImportViewModel.cs | 80 + .../ViewModels/Customer/CustomerViewModel.cs | 102 + .../CancelOrderOprationViewModel.cs | 36 + .../Dispatchlist/DispatchlistAddViewModel.cs | 59 + .../DispatchlistConfirmDetailViewModel.cs | 111 + .../DispatchlistConfirmPickDetailViewModel.cs | 74 + .../DispatchlistDeliveryViewModel.cs | 49 + .../DispatchlistDetailViewModel.cs | 230 ++ .../DispatchlistFreightfeeViewModel.cs | 61 + .../DispatchlistPackageViewModel.cs | 53 + .../Dispatchlist/DispatchlistSignViewModel.cs | 48 + .../Dispatchlist/DispatchlistViewModel.cs | 281 ++ .../DispatchlistWeightViewModel.cs | 60 + .../Dispatchlist/DispatchpicklistViewModel.cs | 123 + .../Dispatchlist/PreDispatchlistViewModel.cs | 87 + .../FreightfeeExcelmportViewModel.cs | 76 + .../Freightfee/FreightfeeViewModel.cs | 116 + .../GoodsOwner/GoodsownerImportViewModel.cs | 71 + .../GoodsOwner/GoodsownerViewModel.cs | 91 + .../Goodslocation/GoodslocationViewModel.cs | 165 + .../ViewModels/Rolemenu/MenuViewModel.cs | 51 + .../Rolemenu/RolemenuBothViewModel.cs | 51 + .../Rolemenu/RolemenuListViewModel.cs | 56 + .../ViewModels/Rolemenu/RolemenuViewModel.cs | 55 + .../ViewModels/Sku/CategoryViewModel.cs | 77 + .../ViewModels/Sku/SkuDetailViewModel.cs | 195 + .../ViewModels/Sku/SkuSelectViewModel.cs | 73 + .../Entities/ViewModels/Sku/SkuViewModel.cs | 122 + .../ViewModels/Sku/SpuBothViewModel.cs | 30 + .../Entities/ViewModels/Sku/SpuViewModel.cs | 153 + .../Stock/LocationStockManagementViewModel.cs | 71 + .../Stock/StockManagementViewModel.cs | 91 + .../ViewModels/Stock/StockViewModel.cs | 125 + .../Stockadjust/StockadjustViewModel.cs | 149 + .../Stockfreeze/StockfreezeViewModel.cs | 119 + .../Stockmove/StockmoveViewModel.cs | 160 + .../Stockprocess/StockprocessGetViewModel.cs | 103 + .../Stockprocess/StockprocessViewModel.cs | 106 + .../StockprocessWithDetailViewModel.cs | 109 + .../StockprocessdetailViewModel.cs | 115 + .../Stocktaking/StocktakingBasicViewModel.cs | 88 + .../StocktakingConfirmViewModel.cs | 42 + .../Stocktaking/StocktakingViewModel.cs | 99 + .../ViewModels/User/RegisterViewModel.cs | 46 + .../ViewModels/User/UserChangePwdViewModel.cs | 36 + .../User/UserExcelImportViewModel.cs | 74 + .../Entities/ViewModels/User/UserViewModel.cs | 107 + .../WarehouseExcelImportViewModel.cs | 76 + .../Warehouse/WarehouseViewModel.cs | 116 + .../Warehousearea/WarehouseareaViewModel.cs | 99 + .../ViewModels/company/CompanyViewModel.cs | 80 + .../supplier/SupplierExcelImportViewModel.cs | 69 + .../ViewModels/supplier/SupplierViewModel.cs | 114 + .../ViewModels/userrole/UserroleViewModel.cs | 71 + .../IServices/Asn/IAsnService.cs | 128 + .../IServices/Customer/ICustomerService.cs | 66 + .../Dispatchlist/IDispatchlistService.cs | 155 + .../Freightfee/IFreightfeeService.cs | 68 + .../GoodsOwner/IGoodsownerService.cs | 66 + .../Goodslocation/IGoodslocationService.cs | 70 + .../IServices/Rolemenu/IRolemenuService.cs | 66 + .../IServices/Sku/ICategoryService.cs | 53 + .../IServices/Sku/ISpuService.cs | 61 + .../IServices/Stock/IStockService.cs | 51 + .../Stockadjust/IStockadjustService.cs | 68 + .../Stockfreeze/IStockfreezeService.cs | 60 + .../IServices/Stockmove/IStockmoveService.cs | 60 + .../Stockprocess/IStockprocessService.cs | 76 + .../Stocktaking/IStocktakingService.cs | 66 + .../IServices/Warehouse/IWarehouseService.cs | 75 + .../Warehousearea/IWarehouseareaService.cs | 69 + .../IServices/company/ICompanyService.cs | 48 + .../IServices/supplier/ISupplierService.cs | 68 + .../IServices/user/IUserService.cs | 95 + .../IServices/userrole/IUserroleService.cs | 60 + backend/ModernWMS.WMS/ModernWMS.WMS.csproj | 14 + .../ModernWMS.WMS/Services/Asn/AsnService.cs | 656 ++++ .../Services/Customer/CustomerService.cs | 249 ++ .../Dispatchlist/DispatchlistService.cs | 1412 +++++++ .../Services/Freightfee/FreightfeeService.cs | 233 ++ .../Services/GoodsOwner/GoodsownerService.cs | 242 ++ .../Goodslocation/GoodslocationService.cs | 228 ++ .../Services/Rolemenu/RolemenuService.cs | 281 ++ .../Services/Sku/CategoryService.cs | 208 + .../ModernWMS.WMS/Services/Sku/SpuService.cs | 452 +++ .../Services/Stock/StockService.cs | 427 ++ .../Stockadjust/StockadjustService.cs | 280 ++ .../Stockfreeze/StockfreezeService.cs | 288 ++ .../Services/Stockmove/StockmoveService.cs | 449 +++ .../Stockprocess/StockprocessService.cs | 482 +++ .../Stocktaking/StocktakingService.cs | 363 ++ .../Services/Warehouse/WarehouseService.cs | 284 ++ .../Warehousearea/WarehouseareaService.cs | 248 ++ .../Services/company/CompanyService.cs | 159 + .../Services/supplier/SupplierService.cs | 246 ++ .../Services/user/UserService.cs | 560 +++ .../Services/userrole/UserroleService.cs | 225 ++ backend/ModernWMS.sln | 37 + backend/ModernWMS/ModernWMS.csproj | 28 + backend/ModernWMS/Program.cs | 45 + .../ModernWMS/Properties/launchSettings.json | 31 + backend/ModernWMS/Startup.cs | 42 + .../ModernWMS/appsettings.Development.json | 8 + backend/ModernWMS/appsettings.json | 31 + backend/ModernWMS/nlog.config | 34 + backend/ModernWMS/wms.db | Bin 0 -> 151552 bytes backend/README.md | 0 backend/readme.txt | 0 docker/Dockerfile | 18 + docker/backend/web.config | 0 docker/frontend/index.html | 0 docker/nginx.conf | 60 + docker/run.sh | 9 + frontend/.env.development | 6 + frontend/.env.production | 6 + frontend/.eslintrc | 82 + frontend/.gitignore | 24 + frontend/.prettierrc.json | 19 + frontend/.vscode/extensions.json | 3 + frontend/README.md | 4 + frontend/auto-imports.d.ts | 5 + frontend/components.d.ts | 13 + frontend/index.html | 16 + frontend/package-lock.json | 3472 +++++++++++++++++ frontend/package.json | 49 + frontend/readme.txt | 0 frontend/src/App.vue | 83 + .../src/api/base/commodityCategorySetting.ts | 31 + .../api/base/commodityManagementSetting.ts | 33 + frontend/src/api/base/companySetting.ts | 31 + frontend/src/api/base/customer.ts | 46 + frontend/src/api/base/freightSetting.ts | 47 + frontend/src/api/base/ownerOfCargo.ts | 46 + frontend/src/api/base/roleMenu.ts | 55 + frontend/src/api/base/supplier.ts | 46 + frontend/src/api/base/userManagement.ts | 69 + frontend/src/api/base/userRoleSetting.ts | 31 + frontend/src/api/base/warehouseSetting.ts | 124 + frontend/src/api/sys/login.ts | 17 + frontend/src/api/sys/model/userModel.ts | 31 + frontend/src/api/sys/test.ts | 13 + frontend/src/api/wms/deliveryManagement.ts | 221 ++ frontend/src/api/wms/stockAsn.ts | 76 + frontend/src/api/wms/stockManagement.ts | 29 + frontend/src/api/wms/warehouseAdjust.ts | 50 + frontend/src/api/wms/warehouseFreeze.ts | 41 + frontend/src/api/wms/warehouseMove.ts | 50 + frontend/src/api/wms/warehouseProcessing.ts | 66 + frontend/src/api/wms/warehouseTaking.ts | 54 + frontend/src/assets/css/hookComponent.css | 8 + frontend/src/assets/img/WMSTitle.png | Bin 0 -> 88654 bytes frontend/src/assets/img/WMSTitleBig.png | Bin 0 -> 87175 bytes frontend/src/assets/img/gitee.png | Bin 0 -> 1685 bytes frontend/src/assets/img/github.png | Bin 0 -> 1688 bytes frontend/src/assets/img/loginLeft.png | Bin 0 -> 61527 bytes frontend/src/assets/img/loginLeft2.png | Bin 0 -> 31835 bytes frontend/src/assets/img/loginLeft3.png | Bin 0 -> 47716 bytes frontend/src/assets/img/logo.png | Bin 0 -> 64114 bytes frontend/src/assets/img/webLogoMini.png | Bin 0 -> 4921 bytes frontend/src/assets/warehouse.json | 1 + .../src/components/common/function/index.ts | 21 + .../components/common/hookComponent/dialog.ts | 20 + .../common/hookComponent/dialog.vue | 86 + .../common/hookComponent/message.ts | 55 + .../common/hookComponent/message.vue | 33 + frontend/src/components/common/languages.vue | 59 + frontend/src/components/custom-pager.vue | 112 + frontend/src/components/login/login-form.vue | 209 + frontend/src/components/login/loginForm.vue | 120 + .../components/login/user-register-form.vue | 169 + frontend/src/components/lottie.vue | 40 + frontend/src/components/page/nav-list.vue | 126 + .../components/select/commodity-select.vue | 237 ++ .../src/components/select/freight-select.vue | 229 ++ .../src/components/select/location-select.vue | 219 ++ frontend/src/components/select/sku-select.vue | 216 + .../components/system/hookComponent/dialog.ts | 34 + .../system/hookComponent/dialog.vue | 80 + .../system/hookComponent/message.ts | 61 + .../system/hookComponent/message.vue | 33 + frontend/src/components/system/index.ts | 22 + frontend/src/components/system/languages.vue | 71 + frontend/src/components/system/logo.vue | 28 + frontend/src/components/tooltip-btn.vue | 51 + frontend/src/constant/commodityManagement.ts | 11 + frontend/src/constant/style.ts | 73 + frontend/src/constant/system.ts | 2 + frontend/src/constant/vxeTable.ts | 14 + frontend/src/constant/warehouseWorking.ts | 8 + frontend/src/env.d.ts | 6 + frontend/src/languages/i18n.ts | 21 + frontend/src/languages/langs/cnZh.ts | 536 +++ frontend/src/languages/langs/enUs.ts | 536 +++ frontend/src/languages/langs/index.ts | 16 + frontend/src/languages/method/index.ts | 11 + frontend/src/main.ts | 26 + frontend/src/plugins/VXETable/index.ts | 20 + frontend/src/plugins/vuetify/index.ts | 40 + frontend/src/plugins/vuetify/method/index.ts | 11 + frontend/src/router/index.ts | 99 + frontend/src/shims.axios.d.ts | 7 + frontend/src/store/index.ts | 18 + frontend/src/store/module/system.ts | 66 + frontend/src/store/module/user.ts | 75 + frontend/src/style.css | 12 + .../types/Base/CommodityCategorySetting.ts | 16 + .../src/types/Base/CommodityManagement.ts | 62 + frontend/src/types/Base/CompanySetting.ts | 16 + frontend/src/types/Base/Customer.ts | 28 + frontend/src/types/Base/Freight.ts | 12 + frontend/src/types/Base/OwnerOfCargo.ts | 30 + frontend/src/types/Base/RoleMenu.ts | 21 + frontend/src/types/Base/Supplier.ts | 28 + frontend/src/types/Base/UserManagement.ts | 42 + frontend/src/types/Base/UserRoleSetting.ts | 13 + frontend/src/types/Base/Warehouse.ts | 51 + .../DeliveryManagement/DeliveryManagement.ts | 121 + frontend/src/types/Home/Home.ts | 12 + frontend/src/types/Home/HomeHeader.ts | 9 + frontend/src/types/WMS/StockAsn.ts | 70 + frontend/src/types/WMS/StockManagement.ts | 29 + .../types/WarehouseWorking/WarehouseAdjust.ts | 26 + .../types/WarehouseWorking/WarehouseFreeze.ts | 17 + .../types/WarehouseWorking/WarehouseMove.ts | 27 + .../WarehouseWorking/WarehouseProcessing.ts | 31 + .../types/WarehouseWorking/WarehouseTaking.ts | 21 + frontend/src/types/system/Form.ts | 45 + frontend/src/types/system/Store.ts | 28 + frontend/src/types/system/UserModel.ts | 31 + frontend/src/types/system/hookComponent.ts | 28 + frontend/src/types/system/router.ts | 12 + frontend/src/utils/bus.ts | 4 + frontend/src/utils/common.ts | 57 + .../src/utils/dataVerification/formRule.ts | 94 + frontend/src/utils/dataVerification/page.ts | 41 + .../src/utils/dataVerification/tableRule.ts | 83 + frontend/src/utils/exportTable.ts | 69 + frontend/src/utils/format/formatSystem.ts | 17 + frontend/src/utils/format/formatWarehouse.ts | 21 + .../utils/format/formatWarehouseWorking.ts | 35 + frontend/src/utils/http/request.ts | 207 + frontend/src/utils/router/index.ts | 167 + frontend/src/view/Home/home.vue | 47 + frontend/src/view/Home/homeHeader.vue | 224 ++ frontend/src/view/Home/homeSideBar.vue | 180 + frontend/src/view/Home/homepage/homepage.vue | 68 + frontend/src/view/Login/login.vue | 46 + .../add-or-update-category.vue | 143 + .../commodityCategorySetting.vue | 241 ++ .../add-or-update-commodity.vue | 631 +++ .../commodityManagement.vue | 386 ++ .../companySetting/add-or-update-company.vue | 135 + .../base/companySetting/companySetting.vue | 239 ++ .../base/customer/add-or-update-customer.vue | 141 + frontend/src/view/base/customer/customer.vue | 297 ++ .../base/customer/import-customer-table.vue | 227 ++ .../freightSetting/add-or-update-freight.vue | 175 + .../base/freightSetting/freightSetting.vue | 321 ++ .../view/base/freightSetting/import-table.vue | 214 + .../add-or-update-owner-of-cargo.vue | 135 + .../view/base/ownerOfCargo/import-table.vue | 215 + .../view/base/ownerOfCargo/ownerOfCargo.vue | 279 ++ .../base/roleMenu/add-or-update-role-menu.vue | 208 + frontend/src/view/base/roleMenu/roleMenu.vue | 321 ++ .../base/supplier/add-or-update-supplier.vue | 136 + .../base/supplier/import-supplier-table.vue | 216 + frontend/src/view/base/supplier/supplier.vue | 296 ++ .../userManagement/add-or-update-user.vue | 191 + .../view/base/userManagement/import-table.vue | 231 ++ .../base/userManagement/userManagement.vue | 352 ++ .../add-or-update-user-role.vue | 116 + .../base/userRoleSetting/userRoleSetting.vue | 234 ++ .../add-or-update-location.vue | 361 ++ .../add-or-update-reservoir.vue | 213 + .../add-or-update-warehouse.vue | 172 + .../base/warehouseSetting/import-table.vue | 214 + .../base/warehouseSetting/tab-location.vue | 290 ++ .../base/warehouseSetting/tab-reservoir.vue | 265 ++ .../base/warehouseSetting/tab-warehouse.vue | 296 ++ .../warehouseSetting/warehouseSetting.vue | 110 + .../add-or-update-shipment.vue | 327 ++ .../deliveryManagement/confirm-order.vue | 254 ++ .../deliveryManagement/deliveryManagement.vue | 255 ++ .../deliveryManagement/package-confirm.vue | 140 + .../search-delivered-detail.vue | 87 + .../deliveryManagement/shipmentFun.ts | 23 + .../deliveryManagement/tabDelivered.vue | 394 ++ .../deliveryManagement/tabGoodsToBePicked.vue | 238 ++ .../deliveryManagement/tabNewShipment.vue | 205 + .../deliveryManagement/tabPackaged.vue | 267 ++ .../deliveryManagement/tabPicked.vue | 238 ++ .../deliveryManagement/tabPreShipment.vue | 208 + .../deliveryManagement/tabShipment.vue | 424 ++ .../deliveryManagement/tabSignIn.vue | 252 ++ .../deliveryManagement/tabToBeDelivered.vue | 285 ++ .../deliveryManagement/tabToBePackaged.vue | 322 ++ .../deliveryManagement/tabToBeWeighed.vue | 337 ++ .../deliveryManagement/tabWeighed.vue | 272 ++ .../deliveryManagement/to-be-freightfee.vue | 120 + .../to-be-package-confirm.vue | 77 + .../to-be-sign-in-confirm.vue | 82 + .../to-be-weighed-confirm.vue | 98 + .../src/view/pageTemplate/PageTemplate.vue | 245 ++ .../warehouseAdjust/add-or-update-adjust.vue | 282 ++ .../warehouseAdjust/warehouseAdjust.vue | 365 ++ .../warehouseFreeze/add-or-update-freeze.vue | 237 ++ .../warehouseFreeze/warehouseFreeze.vue | 357 ++ .../warehouseMove/add-or-update-move.vue | 311 ++ .../warehouseMove/warehouseMove.vue | 397 ++ .../add-or-update-process.vue | 584 +++ .../warehouseProcessing.vue | 403 ++ .../warehouseTaking/add-or-update-taking.vue | 322 ++ .../warehouseTaking/number-input.vue | 142 + .../warehouseTaking/warehouseTaking.vue | 407 ++ .../wms/stockAsn/add-or-update-notice.vue | 280 ++ frontend/src/view/wms/stockAsn/sku-info.vue | 139 + frontend/src/view/wms/stockAsn/stockAsn.vue | 158 + frontend/src/view/wms/stockAsn/tabNotice.vue | 317 ++ .../view/wms/stockAsn/tabReceiptDetails.vue | 240 ++ .../src/view/wms/stockAsn/tabToDoArrival.vue | 262 ++ .../view/wms/stockAsn/tabToDoGrounding.vue | 286 ++ .../src/view/wms/stockAsn/tabToDoSorting.vue | 308 ++ .../src/view/wms/stockAsn/tabToDoUnload.vue | 291 ++ .../view/wms/stockAsn/update-grounding.vue | 170 + .../src/view/wms/stockAsn/update-sorting.vue | 129 + .../src/view/wms/stockManagement/sku-info.vue | 112 + .../wms/stockManagement/stockManagement.vue | 94 + .../src/view/wms/stockManagement/tabStock.vue | 215 + .../wms/stockManagement/tabStockLocation.vue | 195 + frontend/src/vite-env.d.ts | 1 + frontend/tsconfig.json | 24 + frontend/tsconfig.node.json | 9 + frontend/vite.config.ts | 26 + frontend/yarn.lock | 3262 ++++++++++++++++ image0.png | Bin 0 -> 96842 bytes image1.png | Bin 0 -> 128136 bytes image2.png | Bin 0 -> 209216 bytes logo.png | Bin 0 -> 64114 bytes 441 files changed, 60941 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 backend/ModernWMS.Core/Controller/AccountController.cs create mode 100644 backend/ModernWMS.Core/Controller/BaseController.cs create mode 100644 backend/ModernWMS.Core/DBContext/CallContext.cs create mode 100644 backend/ModernWMS.Core/DBContext/SqlDBContext.cs create mode 100644 backend/ModernWMS.Core/DI/IDependency.cs create mode 100644 backend/ModernWMS.Core/DynamicSearch/QueryCollection.cs create mode 100644 backend/ModernWMS.Core/DynamicSearch/QueryOptions.cs create mode 100644 backend/ModernWMS.Core/DynamicSearch/SearchObject.cs create mode 100644 backend/ModernWMS.Core/Extentions/JsonStringTrimConverter.cs create mode 100644 backend/ModernWMS.Core/Extentions/StartupExtensions.cs create mode 100644 backend/ModernWMS.Core/JWT/ApiResponseHandler.cs create mode 100644 backend/ModernWMS.Core/JWT/CacheManger.cs create mode 100644 backend/ModernWMS.Core/JWT/ClaimValueTypes.cs create mode 100644 backend/ModernWMS.Core/JWT/CurrentUser.cs create mode 100644 backend/ModernWMS.Core/JWT/ITokenManager.cs create mode 100644 backend/ModernWMS.Core/JWT/TokenManager.cs create mode 100644 backend/ModernWMS.Core/JWT/TokenSettings.cs create mode 100644 backend/ModernWMS.Core/Middleware/CorsMiddleware.cs create mode 100644 backend/ModernWMS.Core/Middleware/GlobalExceptionMiddleware.cs create mode 100644 backend/ModernWMS.Core/Middleware/RequestResponseMiddleware.cs create mode 100644 backend/ModernWMS.Core/Middleware/ViewModelActionFiter.cs create mode 100644 backend/ModernWMS.Core/Models/BaseModel.cs create mode 100644 backend/ModernWMS.Core/Models/BatchOperationViewModel.cs create mode 100644 backend/ModernWMS.Core/Models/FormSelectItem.cs create mode 100644 backend/ModernWMS.Core/Models/LoginInputViewModel.cs create mode 100644 backend/ModernWMS.Core/Models/LoginOutputViewModel.cs create mode 100644 backend/ModernWMS.Core/Models/MultiLanguage.cs create mode 100644 backend/ModernWMS.Core/Models/MultiLanguage.en-us.resx create mode 100644 backend/ModernWMS.Core/Models/MultiLanguage.zh-cn.resx create mode 100644 backend/ModernWMS.Core/Models/PageData.cs create mode 100644 backend/ModernWMS.Core/Models/PageSearch.cs create mode 100644 backend/ModernWMS.Core/Models/RefreshTokenInPutViewModel.cs create mode 100644 backend/ModernWMS.Core/Models/ResultModel.cs create mode 100644 backend/ModernWMS.Core/Models/UserroleEntity.cs create mode 100644 backend/ModernWMS.Core/Models/userEntity.cs create mode 100644 backend/ModernWMS.Core/ModernWMS.Core.csproj create mode 100644 backend/ModernWMS.Core/MultiTenancy/ITenantProvider.cs create mode 100644 backend/ModernWMS.Core/MultiTenancy/Tenant.cs create mode 100644 backend/ModernWMS.Core/MultiTenancy/TenantProvider.cs create mode 100644 backend/ModernWMS.Core/Services/AccountService.cs create mode 100644 backend/ModernWMS.Core/Services/BaseService.cs create mode 100644 backend/ModernWMS.Core/Services/IAccountService.cs create mode 100644 backend/ModernWMS.Core/Services/IBaseService.cs create mode 100644 backend/ModernWMS.Core/Swagger/CustomApiVersion.cs create mode 100644 backend/ModernWMS.Core/Swagger/SwaggerSettings.cs create mode 100644 backend/ModernWMS.Core/Swagger/index.html create mode 100644 backend/ModernWMS.Core/Utility/GlobalConsts.cs create mode 100644 backend/ModernWMS.Core/Utility/JsonHelper.cs create mode 100644 backend/ModernWMS.Core/Utility/Md5Helper.cs create mode 100644 backend/ModernWMS.Core/Utility/ModelConvertHelper.cs create mode 100644 backend/ModernWMS.Core/Utility/UtilConvert.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Asn/AsnController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Customer/CustomerController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Dispatchlist/DispatchlistController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Freightfee/FreightfeeController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/GoodsOwner/GoodsownerController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Goodslocation/GoodslocationController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Rolemenu/RolemenuController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Sku/CategoryController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Sku/SpuController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Stock/StockController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Stockadjust/StockadjustController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Stockfreeze/StockfreezeController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Stockmove/StockmoveController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Stockprocess/StockprocessController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Stocktaking/StocktakingController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Warehouse/WarehouseController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/Warehousearea/WarehouseareaController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/company/CompanyController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/supplier/SupplierController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/user/UserController.cs create mode 100644 backend/ModernWMS.WMS/Controllers/userrole/UserroleController.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Asn/AsnEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Asn/AsnsortEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Customer/CustomerEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Dispatchlist/DispatchlistEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Dispatchlist/DispatchpicklistEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Freightfee/FreightfeeEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/GoodsOwner/GoodsownerEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Goodslocation/GoodslocationEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Rolemenu/MenuEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Rolemenu/RolemenuEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Sku/CategoryEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Sku/SkuEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Sku/SpuEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Stock/StockEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Stockadjust/StockadjustEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Stockfreeze/StockfreezeEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Stockmove/StockmoveEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Stockprocess/StockprocessEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Stockprocess/StockprocessdetailEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Stocktaking/StocktakingEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Warehouse/WarehouseEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/Warehousearea/WarehouseareaEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/company/CompanyEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/Models/supplier/SupplierEntity.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Asn/AsnBulkModifyGoodsOwnerViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Asn/AsnViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnFlowInputViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnPutAwayInputViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnsortInputViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Customer/CustomerImportViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Customer/CustomerViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/CancelOrderOprationViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistAddViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistConfirmDetailViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistConfirmPickDetailViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistDeliveryViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistDetailViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistFreightfeeViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistPackageViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistSignViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistWeightViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchpicklistViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/PreDispatchlistViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Freightfee/FreightfeeExcelmportViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Freightfee/FreightfeeViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/GoodsOwner/GoodsownerImportViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/GoodsOwner/GoodsownerViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Goodslocation/GoodslocationViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/MenuViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/RolemenuBothViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/RolemenuListViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/RolemenuViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Sku/CategoryViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Sku/SkuDetailViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Sku/SkuSelectViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Sku/SkuViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Sku/SpuBothViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Sku/SpuViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stock/LocationStockManagementViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stock/StockManagementViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stock/StockViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stockadjust/StockadjustViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stockfreeze/StockfreezeViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stockmove/StockmoveViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessGetViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessWithDetailViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessdetailViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stocktaking/StocktakingBasicViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stocktaking/StocktakingConfirmViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stocktaking/StocktakingViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/User/RegisterViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/User/UserChangePwdViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/User/UserExcelImportViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/User/UserViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Warehouse/WarehouseExcelImportViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Warehouse/WarehouseViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Warehousearea/WarehouseareaViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/company/CompanyViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/supplier/SupplierExcelImportViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/supplier/SupplierViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/userrole/UserroleViewModel.cs create mode 100644 backend/ModernWMS.WMS/IServices/Asn/IAsnService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Customer/ICustomerService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Dispatchlist/IDispatchlistService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Freightfee/IFreightfeeService.cs create mode 100644 backend/ModernWMS.WMS/IServices/GoodsOwner/IGoodsownerService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Goodslocation/IGoodslocationService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Rolemenu/IRolemenuService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Sku/ICategoryService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Sku/ISpuService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Stock/IStockService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Stockadjust/IStockadjustService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Stockfreeze/IStockfreezeService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Stockmove/IStockmoveService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Stockprocess/IStockprocessService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Stocktaking/IStocktakingService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Warehouse/IWarehouseService.cs create mode 100644 backend/ModernWMS.WMS/IServices/Warehousearea/IWarehouseareaService.cs create mode 100644 backend/ModernWMS.WMS/IServices/company/ICompanyService.cs create mode 100644 backend/ModernWMS.WMS/IServices/supplier/ISupplierService.cs create mode 100644 backend/ModernWMS.WMS/IServices/user/IUserService.cs create mode 100644 backend/ModernWMS.WMS/IServices/userrole/IUserroleService.cs create mode 100644 backend/ModernWMS.WMS/ModernWMS.WMS.csproj create mode 100644 backend/ModernWMS.WMS/Services/Asn/AsnService.cs create mode 100644 backend/ModernWMS.WMS/Services/Customer/CustomerService.cs create mode 100644 backend/ModernWMS.WMS/Services/Dispatchlist/DispatchlistService.cs create mode 100644 backend/ModernWMS.WMS/Services/Freightfee/FreightfeeService.cs create mode 100644 backend/ModernWMS.WMS/Services/GoodsOwner/GoodsownerService.cs create mode 100644 backend/ModernWMS.WMS/Services/Goodslocation/GoodslocationService.cs create mode 100644 backend/ModernWMS.WMS/Services/Rolemenu/RolemenuService.cs create mode 100644 backend/ModernWMS.WMS/Services/Sku/CategoryService.cs create mode 100644 backend/ModernWMS.WMS/Services/Sku/SpuService.cs create mode 100644 backend/ModernWMS.WMS/Services/Stock/StockService.cs create mode 100644 backend/ModernWMS.WMS/Services/Stockadjust/StockadjustService.cs create mode 100644 backend/ModernWMS.WMS/Services/Stockfreeze/StockfreezeService.cs create mode 100644 backend/ModernWMS.WMS/Services/Stockmove/StockmoveService.cs create mode 100644 backend/ModernWMS.WMS/Services/Stockprocess/StockprocessService.cs create mode 100644 backend/ModernWMS.WMS/Services/Stocktaking/StocktakingService.cs create mode 100644 backend/ModernWMS.WMS/Services/Warehouse/WarehouseService.cs create mode 100644 backend/ModernWMS.WMS/Services/Warehousearea/WarehouseareaService.cs create mode 100644 backend/ModernWMS.WMS/Services/company/CompanyService.cs create mode 100644 backend/ModernWMS.WMS/Services/supplier/SupplierService.cs create mode 100644 backend/ModernWMS.WMS/Services/user/UserService.cs create mode 100644 backend/ModernWMS.WMS/Services/userrole/UserroleService.cs create mode 100644 backend/ModernWMS.sln create mode 100644 backend/ModernWMS/ModernWMS.csproj create mode 100644 backend/ModernWMS/Program.cs create mode 100644 backend/ModernWMS/Properties/launchSettings.json create mode 100644 backend/ModernWMS/Startup.cs create mode 100644 backend/ModernWMS/appsettings.Development.json create mode 100644 backend/ModernWMS/appsettings.json create mode 100644 backend/ModernWMS/nlog.config create mode 100644 backend/ModernWMS/wms.db create mode 100644 backend/README.md create mode 100644 backend/readme.txt create mode 100644 docker/Dockerfile create mode 100644 docker/backend/web.config create mode 100644 docker/frontend/index.html create mode 100644 docker/nginx.conf create mode 100644 docker/run.sh create mode 100644 frontend/.env.development create mode 100644 frontend/.env.production create mode 100644 frontend/.eslintrc create mode 100644 frontend/.gitignore create mode 100644 frontend/.prettierrc.json create mode 100644 frontend/.vscode/extensions.json create mode 100644 frontend/README.md create mode 100644 frontend/auto-imports.d.ts create mode 100644 frontend/components.d.ts create mode 100644 frontend/index.html create mode 100644 frontend/package-lock.json create mode 100644 frontend/package.json create mode 100644 frontend/readme.txt create mode 100644 frontend/src/App.vue create mode 100644 frontend/src/api/base/commodityCategorySetting.ts create mode 100644 frontend/src/api/base/commodityManagementSetting.ts create mode 100644 frontend/src/api/base/companySetting.ts create mode 100644 frontend/src/api/base/customer.ts create mode 100644 frontend/src/api/base/freightSetting.ts create mode 100644 frontend/src/api/base/ownerOfCargo.ts create mode 100644 frontend/src/api/base/roleMenu.ts create mode 100644 frontend/src/api/base/supplier.ts create mode 100644 frontend/src/api/base/userManagement.ts create mode 100644 frontend/src/api/base/userRoleSetting.ts create mode 100644 frontend/src/api/base/warehouseSetting.ts create mode 100644 frontend/src/api/sys/login.ts create mode 100644 frontend/src/api/sys/model/userModel.ts create mode 100644 frontend/src/api/sys/test.ts create mode 100644 frontend/src/api/wms/deliveryManagement.ts create mode 100644 frontend/src/api/wms/stockAsn.ts create mode 100644 frontend/src/api/wms/stockManagement.ts create mode 100644 frontend/src/api/wms/warehouseAdjust.ts create mode 100644 frontend/src/api/wms/warehouseFreeze.ts create mode 100644 frontend/src/api/wms/warehouseMove.ts create mode 100644 frontend/src/api/wms/warehouseProcessing.ts create mode 100644 frontend/src/api/wms/warehouseTaking.ts create mode 100644 frontend/src/assets/css/hookComponent.css create mode 100644 frontend/src/assets/img/WMSTitle.png create mode 100644 frontend/src/assets/img/WMSTitleBig.png create mode 100644 frontend/src/assets/img/gitee.png create mode 100644 frontend/src/assets/img/github.png create mode 100644 frontend/src/assets/img/loginLeft.png create mode 100644 frontend/src/assets/img/loginLeft2.png create mode 100644 frontend/src/assets/img/loginLeft3.png create mode 100644 frontend/src/assets/img/logo.png create mode 100644 frontend/src/assets/img/webLogoMini.png create mode 100644 frontend/src/assets/warehouse.json create mode 100644 frontend/src/components/common/function/index.ts create mode 100644 frontend/src/components/common/hookComponent/dialog.ts create mode 100644 frontend/src/components/common/hookComponent/dialog.vue create mode 100644 frontend/src/components/common/hookComponent/message.ts create mode 100644 frontend/src/components/common/hookComponent/message.vue create mode 100644 frontend/src/components/common/languages.vue create mode 100644 frontend/src/components/custom-pager.vue create mode 100644 frontend/src/components/login/login-form.vue create mode 100644 frontend/src/components/login/loginForm.vue create mode 100644 frontend/src/components/login/user-register-form.vue create mode 100644 frontend/src/components/lottie.vue create mode 100644 frontend/src/components/page/nav-list.vue create mode 100644 frontend/src/components/select/commodity-select.vue create mode 100644 frontend/src/components/select/freight-select.vue create mode 100644 frontend/src/components/select/location-select.vue create mode 100644 frontend/src/components/select/sku-select.vue create mode 100644 frontend/src/components/system/hookComponent/dialog.ts create mode 100644 frontend/src/components/system/hookComponent/dialog.vue create mode 100644 frontend/src/components/system/hookComponent/message.ts create mode 100644 frontend/src/components/system/hookComponent/message.vue create mode 100644 frontend/src/components/system/index.ts create mode 100644 frontend/src/components/system/languages.vue create mode 100644 frontend/src/components/system/logo.vue create mode 100644 frontend/src/components/tooltip-btn.vue create mode 100644 frontend/src/constant/commodityManagement.ts create mode 100644 frontend/src/constant/style.ts create mode 100644 frontend/src/constant/system.ts create mode 100644 frontend/src/constant/vxeTable.ts create mode 100644 frontend/src/constant/warehouseWorking.ts create mode 100644 frontend/src/env.d.ts create mode 100644 frontend/src/languages/i18n.ts create mode 100644 frontend/src/languages/langs/cnZh.ts create mode 100644 frontend/src/languages/langs/enUs.ts create mode 100644 frontend/src/languages/langs/index.ts create mode 100644 frontend/src/languages/method/index.ts create mode 100644 frontend/src/main.ts create mode 100644 frontend/src/plugins/VXETable/index.ts create mode 100644 frontend/src/plugins/vuetify/index.ts create mode 100644 frontend/src/plugins/vuetify/method/index.ts create mode 100644 frontend/src/router/index.ts create mode 100644 frontend/src/shims.axios.d.ts create mode 100644 frontend/src/store/index.ts create mode 100644 frontend/src/store/module/system.ts create mode 100644 frontend/src/store/module/user.ts create mode 100644 frontend/src/style.css create mode 100644 frontend/src/types/Base/CommodityCategorySetting.ts create mode 100644 frontend/src/types/Base/CommodityManagement.ts create mode 100644 frontend/src/types/Base/CompanySetting.ts create mode 100644 frontend/src/types/Base/Customer.ts create mode 100644 frontend/src/types/Base/Freight.ts create mode 100644 frontend/src/types/Base/OwnerOfCargo.ts create mode 100644 frontend/src/types/Base/RoleMenu.ts create mode 100644 frontend/src/types/Base/Supplier.ts create mode 100644 frontend/src/types/Base/UserManagement.ts create mode 100644 frontend/src/types/Base/UserRoleSetting.ts create mode 100644 frontend/src/types/Base/Warehouse.ts create mode 100644 frontend/src/types/DeliveryManagement/DeliveryManagement.ts create mode 100644 frontend/src/types/Home/Home.ts create mode 100644 frontend/src/types/Home/HomeHeader.ts create mode 100644 frontend/src/types/WMS/StockAsn.ts create mode 100644 frontend/src/types/WMS/StockManagement.ts create mode 100644 frontend/src/types/WarehouseWorking/WarehouseAdjust.ts create mode 100644 frontend/src/types/WarehouseWorking/WarehouseFreeze.ts create mode 100644 frontend/src/types/WarehouseWorking/WarehouseMove.ts create mode 100644 frontend/src/types/WarehouseWorking/WarehouseProcessing.ts create mode 100644 frontend/src/types/WarehouseWorking/WarehouseTaking.ts create mode 100644 frontend/src/types/system/Form.ts create mode 100644 frontend/src/types/system/Store.ts create mode 100644 frontend/src/types/system/UserModel.ts create mode 100644 frontend/src/types/system/hookComponent.ts create mode 100644 frontend/src/types/system/router.ts create mode 100644 frontend/src/utils/bus.ts create mode 100644 frontend/src/utils/common.ts create mode 100644 frontend/src/utils/dataVerification/formRule.ts create mode 100644 frontend/src/utils/dataVerification/page.ts create mode 100644 frontend/src/utils/dataVerification/tableRule.ts create mode 100644 frontend/src/utils/exportTable.ts create mode 100644 frontend/src/utils/format/formatSystem.ts create mode 100644 frontend/src/utils/format/formatWarehouse.ts create mode 100644 frontend/src/utils/format/formatWarehouseWorking.ts create mode 100644 frontend/src/utils/http/request.ts create mode 100644 frontend/src/utils/router/index.ts create mode 100644 frontend/src/view/Home/home.vue create mode 100644 frontend/src/view/Home/homeHeader.vue create mode 100644 frontend/src/view/Home/homeSideBar.vue create mode 100644 frontend/src/view/Home/homepage/homepage.vue create mode 100644 frontend/src/view/Login/login.vue create mode 100644 frontend/src/view/base/commodityCategorySetting/add-or-update-category.vue create mode 100644 frontend/src/view/base/commodityCategorySetting/commodityCategorySetting.vue create mode 100644 frontend/src/view/base/commodityManagement/add-or-update-commodity.vue create mode 100644 frontend/src/view/base/commodityManagement/commodityManagement.vue create mode 100644 frontend/src/view/base/companySetting/add-or-update-company.vue create mode 100644 frontend/src/view/base/companySetting/companySetting.vue create mode 100644 frontend/src/view/base/customer/add-or-update-customer.vue create mode 100644 frontend/src/view/base/customer/customer.vue create mode 100644 frontend/src/view/base/customer/import-customer-table.vue create mode 100644 frontend/src/view/base/freightSetting/add-or-update-freight.vue create mode 100644 frontend/src/view/base/freightSetting/freightSetting.vue create mode 100644 frontend/src/view/base/freightSetting/import-table.vue create mode 100644 frontend/src/view/base/ownerOfCargo/add-or-update-owner-of-cargo.vue create mode 100644 frontend/src/view/base/ownerOfCargo/import-table.vue create mode 100644 frontend/src/view/base/ownerOfCargo/ownerOfCargo.vue create mode 100644 frontend/src/view/base/roleMenu/add-or-update-role-menu.vue create mode 100644 frontend/src/view/base/roleMenu/roleMenu.vue create mode 100644 frontend/src/view/base/supplier/add-or-update-supplier.vue create mode 100644 frontend/src/view/base/supplier/import-supplier-table.vue create mode 100644 frontend/src/view/base/supplier/supplier.vue create mode 100644 frontend/src/view/base/userManagement/add-or-update-user.vue create mode 100644 frontend/src/view/base/userManagement/import-table.vue create mode 100644 frontend/src/view/base/userManagement/userManagement.vue create mode 100644 frontend/src/view/base/userRoleSetting/add-or-update-user-role.vue create mode 100644 frontend/src/view/base/userRoleSetting/userRoleSetting.vue create mode 100644 frontend/src/view/base/warehouseSetting/add-or-update-location.vue create mode 100644 frontend/src/view/base/warehouseSetting/add-or-update-reservoir.vue create mode 100644 frontend/src/view/base/warehouseSetting/add-or-update-warehouse.vue create mode 100644 frontend/src/view/base/warehouseSetting/import-table.vue create mode 100644 frontend/src/view/base/warehouseSetting/tab-location.vue create mode 100644 frontend/src/view/base/warehouseSetting/tab-reservoir.vue create mode 100644 frontend/src/view/base/warehouseSetting/tab-warehouse.vue create mode 100644 frontend/src/view/base/warehouseSetting/warehouseSetting.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/add-or-update-shipment.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/confirm-order.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/deliveryManagement.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/package-confirm.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/search-delivered-detail.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/shipmentFun.ts create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/tabDelivered.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/tabGoodsToBePicked.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/tabNewShipment.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/tabPackaged.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/tabPicked.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/tabPreShipment.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/tabShipment.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/tabSignIn.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/tabToBeDelivered.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/tabToBePackaged.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/tabToBeWeighed.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/tabWeighed.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/to-be-freightfee.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/to-be-package-confirm.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/to-be-sign-in-confirm.vue create mode 100644 frontend/src/view/deliveryManagement/deliveryManagement/to-be-weighed-confirm.vue create mode 100644 frontend/src/view/pageTemplate/PageTemplate.vue create mode 100644 frontend/src/view/warehouseWorking/warehouseAdjust/add-or-update-adjust.vue create mode 100644 frontend/src/view/warehouseWorking/warehouseAdjust/warehouseAdjust.vue create mode 100644 frontend/src/view/warehouseWorking/warehouseFreeze/add-or-update-freeze.vue create mode 100644 frontend/src/view/warehouseWorking/warehouseFreeze/warehouseFreeze.vue create mode 100644 frontend/src/view/warehouseWorking/warehouseMove/add-or-update-move.vue create mode 100644 frontend/src/view/warehouseWorking/warehouseMove/warehouseMove.vue create mode 100644 frontend/src/view/warehouseWorking/warehouseProcessing/add-or-update-process.vue create mode 100644 frontend/src/view/warehouseWorking/warehouseProcessing/warehouseProcessing.vue create mode 100644 frontend/src/view/warehouseWorking/warehouseTaking/add-or-update-taking.vue create mode 100644 frontend/src/view/warehouseWorking/warehouseTaking/number-input.vue create mode 100644 frontend/src/view/warehouseWorking/warehouseTaking/warehouseTaking.vue create mode 100644 frontend/src/view/wms/stockAsn/add-or-update-notice.vue create mode 100644 frontend/src/view/wms/stockAsn/sku-info.vue create mode 100644 frontend/src/view/wms/stockAsn/stockAsn.vue create mode 100644 frontend/src/view/wms/stockAsn/tabNotice.vue create mode 100644 frontend/src/view/wms/stockAsn/tabReceiptDetails.vue create mode 100644 frontend/src/view/wms/stockAsn/tabToDoArrival.vue create mode 100644 frontend/src/view/wms/stockAsn/tabToDoGrounding.vue create mode 100644 frontend/src/view/wms/stockAsn/tabToDoSorting.vue create mode 100644 frontend/src/view/wms/stockAsn/tabToDoUnload.vue create mode 100644 frontend/src/view/wms/stockAsn/update-grounding.vue create mode 100644 frontend/src/view/wms/stockAsn/update-sorting.vue create mode 100644 frontend/src/view/wms/stockManagement/sku-info.vue create mode 100644 frontend/src/view/wms/stockManagement/stockManagement.vue create mode 100644 frontend/src/view/wms/stockManagement/tabStock.vue create mode 100644 frontend/src/view/wms/stockManagement/tabStockLocation.vue create mode 100644 frontend/src/vite-env.d.ts create mode 100644 frontend/tsconfig.json create mode 100644 frontend/tsconfig.node.json create mode 100644 frontend/vite.config.ts create mode 100644 frontend/yarn.lock create mode 100644 image0.png create mode 100644 image1.png create mode 100644 image2.png create mode 100644 logo.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..72de34f --- /dev/null +++ b/.gitignore @@ -0,0 +1,388 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Nuget personal access tokens and Credentials +nuget.config + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +.idea/ +*.sln.iml \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..6c1da5b --- /dev/null +++ b/README.md @@ -0,0 +1,198 @@ +# ModernWMS - 仓库管理系统 + +
+ ModernWMS logo +

ModernWMS

+

开源的简易完整的仓库管理系统

+ + +[![License: MIT](https://img.shields.io/badge/license-MIT-orange.svg)](https://opensource.org/licenses/MIT/) +![Release Version (latest Version)](https://img.shields.io/github/v/release/fjykTec/ModernWMS?color=orange&include_prereleases) +![QR Code Support](https://img.shields.io/badge/QR--Code-Support-orange.svg) +![Docker Support](https://img.shields.io/badge/Docker-Support-orange.svg) +![i18n Support](https://img.shields.io/badge/i18n-Support-orange.svg) +[![MySQL8](https://img.shields.io/badge/MySQL-8.0%2B-orange)](https://www.mysql.com/downloads/) + +![repo size](https://img.shields.io/github/repo-size/fjykTec/ModernWMS) +![GitHub commit activity](https://img.shields.io/github/commit-activity/m/fjykTec/ModernWMS) + + +![GitHub Org's stars](https://img.shields.io/github/stars/ModernWMS?style=social) +![GitHub Follows](https://img.shields.io/github/followers/ModernWMS?style=social) +![GitHub Forks](https://img.shields.io/github/forks/fjykTec/ModernWMS?style=social) +![GitHub Watch](https://img.shields.io/github/watchers/fjykTec/ModernWMS?style=social) +![Gitee Stars](https://gitee.com/modernwms/ModernWMS/badge/star.svg?theme=social) +![Gitee Forks](https://gitee.com/modernwms/ModernWMS/badge/fork.svg?theme=social) + +![.NET](https://img.shields.io/badge/.NET-7.0.0-green) +![Vuetify Cli](https://img.shields.io/badge/Vuetify/cli-3.0.4-green) +![Vue](https://img.shields.io/badge/Vue-3.2.45-green) +![TypeScript](https://img.shields.io/badge/TypeScript-4.1.2-green) +![VXE Table](https://img.shields.io/badge/VXETable-4.3.7-green) +![Vite](https://img.shields.io/badge/Vite-4.0.0-green) +![NodeJS](https://img.shields.io/badge/NodeJS-16.13.1-green) +
+ +# Contents - 目录 + +- [ModernWMS - 仓库管理系统](#modernwms---仓库管理系统) +- [Contents - 目录](#contents---目录) + - [Introduction - 介绍](#introduction---介绍) + - [Requirements - 必要条件](#requirements---必要条件) + - [Linux OS](#linux-os) + - [Windows OS](#windows-os) + - [Installation - 安装](#installation---安装) + - [Linux](#linux) + - [Windows](#windows) + - [Docker](#docker) + - [Usage - 用法](#usage---用法) + - [Contact - 联系](#contact---联系) + - [License - 版权信息](#license---版权信息) + +## Introduction - 介绍 + 该库存管理系统是,我们从多年ERP系统研发中总结出来的一套针对小型物流仓储供应链流程。 在工作过程中我们很多的中小企业,由于IT预算有限,所以无法用上适合他们的系统,却又实实在在存在仓储管理方面的需求,以此我们开始了这个项目。 为了帮助一些有需要的用户。 + +## Requirements - 必要条件 + +### Linux OS + ++ Ubuntu 18.04(LTS),20.04(LTS),22.04(LTS) ++ CentOS Stream 8,9 ++ RHEL 8(8.7),9(9.1) ++ Debian 10,11 ++ openSUSE 15 + +### Windows OS + ++ Windows 10 版本 1607 或更高版本 ++ Windows Server 2012 或更高版本 + +## Installation - 安装 + +### Linux + ++ 下载源码后编译 + + 第一步,下载源码 + + ```bash + cd /tmp/ && wget https://github.com/fjykTec/ModernWMS/archive/refs/heads/master.zip + ``` + + + 第二步,安装.NET SDK 、运行时 和 NodeJS + + ```bash + wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb + sudo dpkg -i packages-microsoft-prod.deb + sudo apt-get update && sudo apt-get install -y dotnet-sdk-7.0 + sudo apt-get install -y aspnetcore-runtime-7.0 + curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash - + sudo apt install -y nodejs + ``` + + + 第三步,编译前端和后端 + + ```bash + cd /tmp/ && unzip master.zip && cd ./ModernWMS-master + mkdir -p /ModernWMS/frontend/ /ModernWMS/backend/ + cd ./frontend/ && yarn && yarn build && cp -rf ./frontend/dist/* /ModernWMS/frontend/ + cd ./backend/ && sudo dotnet publish && cp -rf ./backend/ModernWMS/bin/Debug/net7.0/publish/* /ModernWMS/backend/ + ``` + + + 第四步,安装nginx + + ```bash + cd /tmp/ && wget http://nginx.org/download/nginx-1.18.0.tar.gz + tar -zxvf nginx-1.18.0.tar.gz && cd nginx-1.18.0 + ./configure --prefix=/etc/nginx --with-http_secure_link_module --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module + make && make install + ``` +### Windows + ++ 下载源码后编译部署 + + 第一步,下载源码 + ```PowerShell + cd c:\ + wget -Uri https://github.com/fjykTec/ModernWMS/archive/refs/heads/master.zip -OutFile master.zip + Expand-Archive -Path C:\master.zip -DestinationPath C:\ + ``` + + 第二步,安装.NET SDK 、运行时 和 NodeJS + ```CMD + wget -Uri https://download.visualstudio.microsoft.com/download/pr/35660869-0942-4c5d-8692-6e0d4040137a/4921a36b578d8358dac4c27598519832/dotnet-sdk-7.0.101-win-x64.exe -OutFile dotnet-sdk-7.0.101-win-x64.exe + dotnet-sdk-7.0.100-win-x64.exe /install /quiet /norestart + wget -Uri https://nodejs.org/dist/v16.13.1/node-v16.13.1-x64.msi -OutFile node-v16.13.1-x64.msi + msiexec /i .\node-v16.13.1-x64.msi /passive /norestart + ``` + + 第三步,编译前端和后端 + ``` + md C:\ModernWMS\frontend\ + md C:\ModernWMS\backend\ + cd c:\ModernWMS-master\backend + dotnet publish + copy-item -path ".\backend\ModernWMS\bin\Debug\net7.0\publish\" -destination "C:\ModernWMS\backend\" -recurse + cd c:\ModernWMS-master\frontend + yarn && yarn build + copy-item -path ".\frontend\dist\" -destination "C:\ModernWMS\frontend\" -recurse + ``` + + 第四步,安装nginx并启动 + ``` + cd C:\ + wget -Uri http://nginx.org/download/nginx-1.16.1.zip -OutFile nginx-1.16.1.zip + Expand-Archive -Path C:\nginx-1.16.1.zip -DestinationPath C:\ + start .\nginx-1.16.1\nginx.exe + cd C:\ModernWMS\backend\ + dotnet ModernWMS.dll --urls http://0.0.0.0:20011 + ``` + +### Docker + + ++ 下载源码后编译 + + 第一步,下载源码 + + ```bash + cd /tmp/ && wget https://github.com/fjykTec/ModernWMS/archive/refs/heads/master.zip + ``` + + + 第二步,编译前端和后端 + + ```bash + cd /tmp/ && unzip master.zip && cd ./ModernWMS-master + cd ./frontend/ && yarn && yarn build && cp -rf ./frontend/dist/* ./docker/frontend/ + cd ./backend/ && sudo dotnet publish && cp -rf ./backend/ModernWMS/bin/Debug/net7.0/publish/* ./docker/backend/ + ``` + + 第三步,部署 + + ```bash + cd /tmp/ModernWMS-master/docker/ + docker build -t modernwms:1.0 . + docker run -d -p 80:80 modernwms:1.0 /bin/bash ./run.sh + ``` +## Usage - 用法 + + ``` + 打开浏览器,进入:http://127.0.0.1 或者 http://部署电脑的IP地址 + ``` +

+ 体验地址入口 +

  + + ![image0.png](https://gitee.com/modernwms/ModernWMS/raw/develop/image0.png) + + ![image1.png](https://gitee.com/modernwms/ModernWMS/raw/develop/image1.png) + + ![image2.png](https://gitee.com/modernwms/ModernWMS/raw/develop/image2.png) + +## Contact - 联系 + +

+ 提交一个Bug +

+

+ 提交一个建议 +

+

+ 加入QQ群 757128595 +

+ +## License - 版权信息 +该项目使用的是 [MIT](https://opensource.org/licenses/MIT/) 协议. 详情查阅[LICENSE.txt](https://github.com/fjykTec/ModernWMS/master/LICENSE).必须遵守此协议。 \ No newline at end of file diff --git a/backend/ModernWMS.Core/Controller/AccountController.cs b/backend/ModernWMS.Core/Controller/AccountController.cs new file mode 100644 index 0000000..ab54aa1 --- /dev/null +++ b/backend/ModernWMS.Core/Controller/AccountController.cs @@ -0,0 +1,138 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Logging; +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; +using ModernWMS.Core.Services; + +namespace ModernWMS.Core.Controller +{ + /// + /// account + /// + [Route("[controller]")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class AccountController : BaseController + { + /// + /// token manger + /// + private readonly ITokenManager _tokenManager; + /// + /// Log helper + /// + private readonly ILogger _logger; + + /// + /// cache helper + /// + private readonly CacheManager _cacheManager; + + /// + /// account service class + /// + private readonly IAccountService _accountService; + + /// + /// Localizer + /// + private readonly IStringLocalizer _stringLocalizer; + /// + /// Structure + /// + /// logger helper + /// token manger + /// cache helper + /// account service class + /// Localizer + public AccountController(ILogger logger + , ITokenManager tokenManager + , CacheManager cacheManager + , IAccountService accountService + , IStringLocalizer stringLocalizer + ) + { + this._tokenManager = tokenManager; + this._logger = logger; + this._cacheManager = cacheManager; + this._accountService = accountService; + this._stringLocalizer = stringLocalizer; + } + + #region Login + + /// + /// login + /// + /// user's account infomation + /// + [AllowAnonymous] + [HttpPost("/login")] + public async Task> LoginAsync(LoginInputViewModel loginAccount) + { + + var user = await _accountService.Login(loginAccount,CurrentUser); + if (user != null) + { + var result = _tokenManager.GenerateToken( + new CurrentUser + { + user_id = user.user_id, + user_name = user.user_name, + user_num = user.user_num, + user_role = user.user_role, + tenant_id = user.tenant_id + } + ); + string rt = this._tokenManager.GenerateRefreshToken(); + + user.access_token = result.token; + user.expire = result.expire; + user.refresh_token = rt; + + await _cacheManager.TokenSet(user.user_id, "WebRefreshToken", rt, _tokenManager.GetRefreshTokenExpireMinute()); + + return ResultModel.Success(user); + } + else + { + return ResultModel.Error(_stringLocalizer["login_failed"]); + } + } + /// + /// get a new token + /// + /// old access token and refreshtoken key + /// + [AllowAnonymous] + [HttpPost("/refresh-token")] + public async Task> RefreshToken([FromBody] RefreshTokenInPutViewModel inPutViewModel) + { + var currentUser = this._tokenManager.GetCurrentUser(inPutViewModel.AccessToken); + + var flag = _cacheManager.Is_Token_Exist(currentUser.user_id, "WebRefreshToken", _tokenManager.GetRefreshTokenExpireMinute()); + if (!flag) + { + return ResultModel.Error("refreshtoken_failure"); + } + else + { + var result = _tokenManager.GenerateToken(currentUser); + return ResultModel.Success(result.token); + } + + } + #endregion + #region hello world + [AllowAnonymous] + [HttpPost("/hello-world")] + public ResultModel hello_world() + { + return ResultModel.Success(_accountService.HelloWorld()); + } + #endregion + } +} diff --git a/backend/ModernWMS.Core/Controller/BaseController.cs b/backend/ModernWMS.Core/Controller/BaseController.cs new file mode 100644 index 0000000..e213965 --- /dev/null +++ b/backend/ModernWMS.Core/Controller/BaseController.cs @@ -0,0 +1,40 @@ + +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using ModernWMS.Core.JWT; +using ModernWMS.Core.Utility; +using System.Linq; + +namespace ModernWMS.Core.Controller +{ + /// + /// base controller + /// + //[Authorize] + [Produces("application/json")] + public class BaseController : ControllerBase + { + /// + /// current user + /// + public CurrentUser CurrentUser + { + get + { + if (User != null && User.Claims.ToList().Count > 0) + { + var Claim = User.Claims.First(claim => claim.Type == ClaimValueTypes.Json); + return Claim == null ? new CurrentUser() : JsonHelper.DeserializeObject(Claim.Value); + } + else + { + return new CurrentUser(); + } + } + } + + public BaseController() + { + } + } +} diff --git a/backend/ModernWMS.Core/DBContext/CallContext.cs b/backend/ModernWMS.Core/DBContext/CallContext.cs new file mode 100644 index 0000000..845e4ad --- /dev/null +++ b/backend/ModernWMS.Core/DBContext/CallContext.cs @@ -0,0 +1,30 @@ +using System.Collections.Concurrent; +using System.Threading; + +namespace ModernWMS.Core.DBContext +{ + /// + /// 当前连接的上下文 + /// + public static class CallContext + { + /// + /// 静态字典 + /// + static ConcurrentDictionary> state = new ConcurrentDictionary>(); + /// + /// 设置值 + /// + /// 键 + /// 值 + public static void SetData(string name, object data) => + state.GetOrAdd(name, _ => new AsyncLocal()).Value = data; + /// + /// 获取值 + /// + /// 键 + /// + public static object GetData(string name) => + state.TryGetValue(name, out AsyncLocal data) ? data.Value : null; + } +} diff --git a/backend/ModernWMS.Core/DBContext/SqlDBContext.cs b/backend/ModernWMS.Core/DBContext/SqlDBContext.cs new file mode 100644 index 0000000..5d87cd9 --- /dev/null +++ b/backend/ModernWMS.Core/DBContext/SqlDBContext.cs @@ -0,0 +1,128 @@ + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.Extensions.Logging; +using System.ComponentModel; +using System.Data; +using System.Data.Common; +using System.Reflection; +using ModernWMS.Core; +using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; + +namespace ModernWMS.Core.DBContext +{ + /// + /// SqlDBContext + /// + public class SqlDBContext : DbContext + { + /// + /// current user's tenant_id + /// + public byte tenant_id { get; set; } = 1; + + /// + /// Database + /// + /// + public DatabaseFacade GetDatabase() => Database; + + + + + /// + /// s + /// + /// options + public SqlDBContext(DbContextOptions options) : base(options) + { + + } + + #region overwrite + /// + /// Auto Mapping Entity + /// + /// ModelBuilder + private void MappingEntityTypes(ModelBuilder modelBuilder) + { + var baseType = typeof(Models.BaseModel); + var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; + var referencedAssemblies = System.IO.Directory.GetFiles(path, $"ModernWMS*.dll").Select(Assembly.LoadFrom).ToArray(); + var list = referencedAssemblies + .SelectMany(a => a.DefinedTypes) + .Select(type => type.AsType()) + .Where(x => x != baseType && baseType.IsAssignableFrom(x)).ToList(); + if (list != null && list.Any()) + { + list.ForEach(t => + { + var entityType = modelBuilder.Model.FindEntityType(t); + if (entityType == null) + { + modelBuilder.Model.AddEntityType(t); + } + }); + } + } + /// + /// overwrite OnModelCreating + /// + /// + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + MappingEntityTypes(modelBuilder); +/* foreach (var entityType in modelBuilder.Model.GetEntityTypes()) + { + if (typeof(Models.IHasTenant).IsAssignableFrom(entityType.ClrType)) + { + ConfigureGlobalFiltersMethodInfo + .MakeGenericMethod(entityType.ClrType) + .Invoke(this, new object[] { modelBuilder }); + } + }*/ + base.OnModelCreating(modelBuilder); + } + + /// + /// create DbSet + /// + /// 实体 + /// + public virtual DbSet GetDbSet() where T : class + { + if (Model.FindEntityType(typeof(T)) != null) + { + return Set(); + } + else + { + throw new Exception($"type {typeof(T).Name} is not add into DbContext "); + } + } + /// + /// over write EnsureCreated + /// + /// + public virtual bool EnsureCreated() + { + return Database.EnsureCreated(); + } + /// + /// over write OnConfiguring + /// + /// + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + base.OnConfiguring(optionsBuilder); + } + + + #endregion + + + + + + } +} diff --git a/backend/ModernWMS.Core/DI/IDependency.cs b/backend/ModernWMS.Core/DI/IDependency.cs new file mode 100644 index 0000000..649dbe0 --- /dev/null +++ b/backend/ModernWMS.Core/DI/IDependency.cs @@ -0,0 +1,7 @@ + +namespace ModernWMS.Core.DI +{ + public interface IDependency + { + } +} diff --git a/backend/ModernWMS.Core/DynamicSearch/QueryCollection.cs b/backend/ModernWMS.Core/DynamicSearch/QueryCollection.cs new file mode 100644 index 0000000..e882713 --- /dev/null +++ b/backend/ModernWMS.Core/DynamicSearch/QueryCollection.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.Core.DynamicSearch +{ + /// + /// Dynamic Query + /// + public class QueryCollection : Collection + { + /// + /// Expression + /// + /// entity + /// + public static Expression> True() { return f => true; } + /// + /// Expression + /// + /// entity + /// condition + /// + public Expression> AsExpression(Condition? condition = Condition.AndAlso) where T : class + { + if (this.Count == 0) + { + return True(); + } + Type targetType = typeof(T); + TypeInfo typeInfo = targetType.GetTypeInfo(); + var parameter = Expression.Parameter(targetType, "m"); + Expression expression = null; + Func Append = (exp1, exp2) => + { + if (exp1 == null) + { + return exp2; + } + return (condition ?? Condition.OrElse) == Condition.OrElse ? Expression.OrElse(exp1, exp2) : Expression.AndAlso(exp1, exp2); + }; + foreach (var item in this) + { + var property = typeInfo.GetProperty(item.Name); + if (property == null || + !property.CanRead || + (item.Text.Trim().Length == 0)) + { + continue; + } + if (item.Text.Length == 0) + { + item.Text = item.Value.ToString(); + } + Type realType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType; + if (item.Text.Length > 0) + { + if (item.Type.ToUpper().Equals("DATETIMEPICKER") + && (item.Operator == Operators.LessThanOrEqual || item.Operator == Operators.LessThan)) + { + item.Text = Convert.ToDateTime(item.Text).ToString("yyyy-MM-dd") + " 23:59:59"; + } + item.Value = Convert.ChangeType(item.Text, realType); + } + Expression> valueLamba = () => item.Value; + switch (item.Operator) + { + case Operators.Equal: + { + expression = Append(expression, Expression.Equal(Expression.Property(parameter, item.Name), + Expression.Convert(valueLamba.Body, property.PropertyType))); + break; + } + case Operators.GreaterThan: + { + expression = Append(expression, Expression.GreaterThan(Expression.Property(parameter, item.Name), + Expression.Convert(valueLamba.Body, property.PropertyType))); + break; + } + case Operators.GreaterThanOrEqual: + { + expression = Append(expression, Expression.GreaterThanOrEqual(Expression.Property(parameter, item.Name), + Expression.Convert(valueLamba.Body, property.PropertyType))); + break; + } + case Operators.LessThan: + { + expression = Append(expression, Expression.LessThan(Expression.Property(parameter, item.Name), + Expression.Convert(valueLamba.Body, property.PropertyType))); + break; + } + case Operators.LessThanOrEqual: + { + expression = Append(expression, Expression.LessThanOrEqual(Expression.Property(parameter, item.Name), + Expression.Convert(valueLamba.Body, property.PropertyType))); + break; + } + case Operators.Contains: + { + var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name))); + var contains = Expression.Call(Expression.Property(parameter, item.Name), "Contains", null, + Expression.Convert(valueLamba.Body, property.PropertyType)); + expression = Append(expression, Expression.AndAlso(nullCheck, contains)); + break; + } + } + } + if (expression == null) + { + return null; + } + return ((Expression>)Expression.Lambda(expression, parameter)); + } + } +} diff --git a/backend/ModernWMS.Core/DynamicSearch/QueryOptions.cs b/backend/ModernWMS.Core/DynamicSearch/QueryOptions.cs new file mode 100644 index 0000000..5425beb --- /dev/null +++ b/backend/ModernWMS.Core/DynamicSearch/QueryOptions.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.Core.DynamicSearch +{ + /// + /// DynamicSearch Operators + /// + public enum Operators + { + /// + /// None + /// + None = 0, + /// + /// Equal = + /// + Equal = 1, + /// + /// GreaterThan + /// + GreaterThan = 2, + /// + /// GreaterThanOrEqual + /// + GreaterThanOrEqual = 3, + /// + /// LessThan + /// + LessThan = 4, + /// + /// LessThanOrEqual + /// + LessThanOrEqual = 5, + /// + /// Contains + /// + Contains = 6 + } + /// + /// Condition + /// + public enum Condition + { + /// + /// OR + /// + OrElse = 1, + /// + /// AND + /// + AndAlso = 2 + } + /// + /// select item combox + /// + public class ComboxItem + { + /// + /// value + /// + public string value { get; set; } + /// + /// text + /// + public string text { get; set; } + } +} diff --git a/backend/ModernWMS.Core/DynamicSearch/SearchObject.cs b/backend/ModernWMS.Core/DynamicSearch/SearchObject.cs new file mode 100644 index 0000000..7506ce7 --- /dev/null +++ b/backend/ModernWMS.Core/DynamicSearch/SearchObject.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.Core.DynamicSearch +{ + /// + /// SearchObject + /// + public class SearchObject + { + /// + /// sort + /// + public int Sort { get; set; } = 0; + + /// + /// label + /// + public string Label { get; set; } = string.Empty; + + /// + /// name + /// + public string Name { get; set; } = string.Empty; + + /// + /// type + /// + public string Type { get; set; } = string.Empty; + + /// + /// operator + /// + public Operators Operator { get; set; } = Operators.Equal; + + /// + /// text + /// + public string Text { get; set; } = string.Empty; + + /// + /// value + /// + public object Value { get; set; } = new object(); + + /// + /// select item combox list + /// + public List comboxItem { get; set; } = new List(); + + } +} diff --git a/backend/ModernWMS.Core/Extentions/JsonStringTrimConverter.cs b/backend/ModernWMS.Core/Extentions/JsonStringTrimConverter.cs new file mode 100644 index 0000000..9381699 --- /dev/null +++ b/backend/ModernWMS.Core/Extentions/JsonStringTrimConverter.cs @@ -0,0 +1,62 @@ +using Newtonsoft.Json; +using System; + +namespace ModernWMS.Core.Extentions +{ + /// + /// JSON extentions + /// + public class JsonStringTrimConverter : JsonConverter + { + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + public override bool CanConvert(Type objectType) + { + return objectType == typeof(string); + } + /// + /// Reads the JSON representation of the object. + /// + /// The Newtonsoft.Json.JsonReader to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (objectType == typeof(string) && reader.Value != null) + { + if (reader.TokenType == JsonToken.Date) + { + return Convert.ToDateTime(reader.Value).ToString("yyyy-MM-dd HH:mm:ss"); + } + else + { + return (reader.Value as string).Trim(); + } + } + return reader.Value; + } + /// + /// Writes the JSON representation of the object. + /// + /// The Newtonsoft.Json.JsonWriter to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var text = (string)value; + if (text == null) + { + writer.WriteNull(); + } + else + { + writer.WriteValue(text.Trim()); + } + } + } +} diff --git a/backend/ModernWMS.Core/Extentions/StartupExtensions.cs b/backend/ModernWMS.Core/Extentions/StartupExtensions.cs new file mode 100644 index 0000000..66ce479 --- /dev/null +++ b/backend/ModernWMS.Core/Extentions/StartupExtensions.cs @@ -0,0 +1,292 @@ +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.EntityFrameworkCore; +using Pomelo.EntityFrameworkCore.MySql; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.Filters; +using System.Reflection; +using System.Text; +using ModernWMS.Core.DBContext; +using System.Reflection.PortableExecutable; +using Microsoft.Extensions.Logging.Debug; +using ModernWMS.Core.Swagger; +using ModernWMS.Core.JWT; +using Newtonsoft.Json; +using Microsoft.AspNetCore.Cors.Infrastructure; +using ModernWMS.Core.Middleware; +using Microsoft.Extensions.DependencyModel; +using ModernWMS.Core.DI; +using Microsoft.Extensions.Localization; +using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; +using Microsoft.EntityFrameworkCore.Migrations.Internal; + +namespace ModernWMS.Core.Extentions +{ + public static class StartupExtensions + { + public static void AddExtensionsService(this IServiceCollection services, IConfiguration configuration) + { + services.AddLocalization(); + services.AddSingleton((sp) => + { + var sharedLocalizer = sp.GetRequiredService>(); + return sharedLocalizer; + }); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(factory => + { + var cache = new MemoryCache(new MemoryCacheOptions()); + return cache; + }); + var Mysql_connection = configuration.GetConnectionString("MySqlConn"); + var SqlLite_connection = configuration.GetConnectionString("SqlLiteConn"); + var database_config = configuration.GetSection("Database")["db"]; + services.AddDbContextPool(t => + { + if(database_config == "SqlLite") + { + t.UseSqlite(SqlLite_connection, b => b.MigrationsAssembly("ModernWMS")); + } + else + { + t.UseMySql(Mysql_connection, new MySqlServerVersion(new Version(8, 0, 26))); + } + + t.EnableSensitiveDataLogging(); + t.UseLoggerFactory(new LoggerFactory(new[] { new DebugLoggerProvider() })); + }, 100); ; + services.AddMemoryCache( ); + services.AddScoped(); + services.AddSwaggerService(configuration, AppContext.BaseDirectory); + services.AddTokenGeneratorService(configuration); + services.RegisterAssembly(); + services.AddControllers(c => + { + c.Filters.Add(typeof(ViewModelActionFiter)); + c.MaxModelValidationErrors = 99999; + }).ConfigureApiBehaviorOptions(o => + { + o.SuppressModelStateInvalidFilter = true; + })//format + .AddNewtonsoftJson(options => + { + options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; + options.SerializerSettings.Converters.Add(new JsonStringTrimConverter()); + options.SerializerSettings.Formatting = Formatting.Indented; + options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(); + }).AddDataAnnotationsLocalization(options => { + options.DataAnnotationLocalizerProvider = (type, factory) => + factory.Create(typeof(ModernWMS.Core.MultiLanguage)); + }); ; + + } + public static void UseExtensionsConfigure(this IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider, IConfiguration configuration) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + app.UseStaticFiles(); + app.UseSwaggerConfigure(configuration); + app.UseRouting(); + app.UseMiddleware(); + app.UseTokenGeneratorConfigure(configuration); + app.UseAuthorization(); + app.UseMiddleware(); + var support_languages = new[] { "zh-cn", "en-us" }; + var localization_options = new RequestLocalizationOptions() + .SetDefaultCulture(support_languages[0]) + .AddSupportedCultures(support_languages) + .AddSupportedUICultures(support_languages); + app.UseRequestLocalization(localization_options); + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + #region Swagger + /// + /// Swagger + /// + /// 服务容器 + /// 配置文件 + /// 主目录 + private static void AddSwaggerService(this IServiceCollection services, IConfiguration configuration, string BaseDirectory) + { + if (services == null) + { + throw new ArgumentNullException(nameof(services)); + } + var swaggerSettings = configuration.GetSection("SwaggerSettings"); + + var provider = services.Configure(swaggerSettings).BuildServiceProvider(); + var settings = provider.GetService>()?.Value; + + if (settings != null && settings.Name.Equals("ModernWMS")) + { + services.AddSwaggerGen(c => + { + typeof(CustomApiVersion.ApiVersions).GetEnumNames().ToList().ForEach(version => + { + c.SwaggerDoc(version, new OpenApiInfo + { + Title = settings.ApiTitle, + Version = settings.ApiVersion, + Description = settings.Description + }); + }); + + + if (settings.XmlFiles != null && settings.XmlFiles.Count > 0) + { + settings.XmlFiles.ForEach(fileName => + { + if (File.Exists(Path.Combine(BaseDirectory, fileName))) + { + c.IncludeXmlComments(Path.Combine(BaseDirectory, fileName), true); + } + }); + } + + c.OperationFilter(); + c.OperationFilter(); + c.OperationFilter(); + + + c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme + { + Description = "please input Bearer {token}", + Name = "Authorization", + In = ParameterLocation.Header, + Type = SecuritySchemeType.ApiKey + }); + c.SwaggerGeneratorOptions.DescribeAllParametersInCamelCase = false; + + }); + } + } + /// + /// register Swagger + /// + /// + /// 配置文件 + private static void UseSwaggerConfigure(this IApplicationBuilder app, IConfiguration configuration) + { + + var swaggerSettings = configuration.GetSection("SwaggerSettings"); + + if (swaggerSettings != null && swaggerSettings["Name"].Equals("ModernWMS")) + { + app.UseSwagger(); + + app.UseSwaggerUI(c => + { + typeof(CustomApiVersion.ApiVersions).GetEnumNames().OrderBy(e => e).ToList().ForEach(version => + { + c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{swaggerSettings["Name"]} {version}"); + }); + + c.IndexStream = () => Assembly.GetExecutingAssembly().GetManifestResourceStream("ModernWMS.Core.Swagger.index.html"); + c.RoutePrefix = ""; + + }); + + } + } + #endregion + + #region JWT + /// + /// register JWT + /// + /// services + /// configuration + private static void AddTokenGeneratorService(this IServiceCollection services, IConfiguration configuration) + { + + if (services == null) + { + throw new ArgumentNullException(nameof(services)); + } + var tokenSettings = configuration.GetSection("TokenSettings"); + services.Configure(tokenSettings); + services.AddTransient(); + + services.AddAuthentication(options => + { + options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = nameof(ApiResponseHandler); + options.DefaultForbidScheme = nameof(ApiResponseHandler); + } + ) + .AddJwtBearer(options => + { + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateAudience = true, + ValidAudience = tokenSettings["Audience"], + ValidateIssuer = true, + ValidIssuer = tokenSettings["Issuer"], + ValidateLifetime = true, + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenSettings["SigningKey"])), + ClockSkew = TimeSpan.Zero + }; + }) + .AddScheme(nameof(ApiResponseHandler), o => { }); + + } + + private static void UseTokenGeneratorConfigure(this IApplicationBuilder app, IConfiguration configuration) + { + app.UseAuthentication(); + } + #endregion + + #region dynamic injection + /// + /// judge the dll to be injected by IDependency + /// + /// services + private static IServiceCollection RegisterAssembly(this IServiceCollection services) + { + + + var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; + var referencedAssemblies = System.IO.Directory.GetFiles(path, "ModernWMS*.dll").Select(Assembly.LoadFrom).ToArray(); + + var types = referencedAssemblies + .SelectMany(a => a.DefinedTypes) + .Select(type => type.AsType()) + .Where(x => x != typeof(IDependency) && typeof(IDependency).IsAssignableFrom(x)).ToArray(); + var implementTypes = types.Where(x => x.IsClass).ToArray(); + var interfaceTypes = types.Where(x => x.IsInterface).ToArray(); + foreach (var implementType in implementTypes) + { + var interfaceType = interfaceTypes.FirstOrDefault(x => x.IsAssignableFrom(implementType)); + if (interfaceType != null) + services.AddScoped(interfaceType, implementType); + } + + services.AddScoped(); + return services; + } + #endregion + + + } +} diff --git a/backend/ModernWMS.Core/JWT/ApiResponseHandler.cs b/backend/ModernWMS.Core/JWT/ApiResponseHandler.cs new file mode 100644 index 0000000..2ee735f --- /dev/null +++ b/backend/ModernWMS.Core/JWT/ApiResponseHandler.cs @@ -0,0 +1,85 @@ + +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; +using System; +using System.Threading.Tasks; +using System.Text.Encodings.Web; +using Microsoft.Extensions.Logging; +using ModernWMS.Core.Models; +using System.Linq; +using ModernWMS.Core.Utility; +using ModernWMS.Core.JWT; +namespace ModernWMS.Core.JWT +{ + /// + /// Custom Processing Unit + /// + public class ApiResponseHandler : AuthenticationHandler + { + + /// + /// token manager + /// + private readonly ITokenManager _tokenManager; + /// + /// cache manager + /// + private readonly CacheManager _cacheManager; + + /// + /// constructor + /// + /// options + /// logger + /// encoder + /// + /// tokenManager + /// cacheManagerparam> + public ApiResponseHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock + , ITokenManager tokenManager + , CacheManager cacheManager) + : base(options, logger, encoder, clock) + { + this._tokenManager = tokenManager; + _cacheManager = cacheManager; + } + /// + /// handle authority + /// + /// + protected override async Task HandleAuthenticateAsync() + { + var token = Request.Headers["Authorization"].ObjToString().Replace("Bearer ", ""); + var currentUser = this._tokenManager.GetCurrentUser(token); + var flag = _cacheManager.Is_Token_Exist(currentUser.user_id, "WebToken", _tokenManager.GetRefreshTokenExpireMinute()); + if (!flag) + { + return AuthenticateResult.Fail("Sorry, you don't have the authority required!"); + } + throw new NotImplementedException(); + } + /// + /// authentication + /// + /// 参数 + /// + protected override async Task HandleChallengeAsync(AuthenticationProperties properties) + { + Response.ContentType = "application/json"; + Response.StatusCode = StatusCodes.Status401Unauthorized; + await Response.WriteAsync(JsonHelper.SerializeObject(ResultModel.Error("Sorry, please sign in first!", 403))); + } + /// + /// access denied + /// + /// + /// + protected override async Task HandleForbiddenAsync(AuthenticationProperties properties) + { + Response.ContentType = "application/json"; + Response.StatusCode = StatusCodes.Status403Forbidden; + await Response.WriteAsync(JsonHelper.SerializeObject(ResultModel.Error("Sorry, you don't have the authority required!", 403))); + } + } +} diff --git a/backend/ModernWMS.Core/JWT/CacheManger.cs b/backend/ModernWMS.Core/JWT/CacheManger.cs new file mode 100644 index 0000000..25538ea --- /dev/null +++ b/backend/ModernWMS.Core/JWT/CacheManger.cs @@ -0,0 +1,152 @@ +using Microsoft.Extensions.Caching.Memory; +using Newtonsoft.Json.Linq; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; + +namespace ModernWMS.Core.JWT +{ + public class CacheManager + { + + public static CacheManager Default = new CacheManager(); + + private IMemoryCache _cache = new MemoryCache(new MemoryCacheOptions()); + + public CacheManager() + { + + } + + /// + /// get value by key + /// + /// type of value + /// key + /// + public T Get(string key) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); + T value; + _cache.TryGetValue(key, out value); + return value; + } + + + /// + /// set cache + /// + /// key + /// value + public void Set_NotExpire(string key, T value) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); + + T v; + if (_cache.TryGetValue(key, out v)) + _cache.Remove(key); + _cache.Set(key, value); + } + + /// + /// set cache with expire + /// + /// key + /// value + public void Set_SlidingExpire(string key, T value, TimeSpan span) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); + + T v; + if (_cache.TryGetValue(key, out v)) + _cache.Remove(key); + _cache.Set(key, value, new MemoryCacheEntryOptions() + { + SlidingExpiration = span + }); + } + + + public void Set_AbsoluteExpire(string key, T value, TimeSpan span) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); + + T v; + if (_cache.TryGetValue(key, out v)) + _cache.Remove(key); + _cache.Set(key, value, span); + } + + public void Set_SlidingAndAbsoluteExpire(string key, T value, TimeSpan slidingSpan, TimeSpan absoluteSpan) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); + + T v; + if (_cache.TryGetValue(key, out v)) + _cache.Remove(key); + _cache.Set(key, value, new MemoryCacheEntryOptions() + { + SlidingExpiration = slidingSpan, + AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds(absoluteSpan.TotalMilliseconds) + }); + } + + /// + /// remove cache by key + /// + /// key + public void Remove(string key) + { + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); + + _cache.Remove(key); + } + + /// + /// dispose + /// + public void Dispose() + { + if (_cache != null) + _cache.Dispose(); + GC.SuppressFinalize(this); + } + + #region TokenHelper + public bool Is_Token_Exist(int userID, string type, int expireMinute) + { + var key = $"ModernWMS_{type}_{userID}"; + if (string.IsNullOrWhiteSpace(key)) + throw new ArgumentNullException(nameof(key)); + T value; + if (_cache.TryGetValue(key, out value)) + { + Set_SlidingExpire(key, value, TimeSpan.FromMinutes(expireMinute) ); + return true; + } + return false; + } + public async Task TokenSet(int userID, string type, string token, int expireMinute) + { + string key = $"ModernWMS_{type}_{userID}"; + try + { + Set_AbsoluteExpire(key, token, TimeSpan.FromMinutes(expireMinute)); + } + catch + { + return false; + } + return true; + } + #endregion + } +} + diff --git a/backend/ModernWMS.Core/JWT/ClaimValueTypes.cs b/backend/ModernWMS.Core/JWT/ClaimValueTypes.cs new file mode 100644 index 0000000..e96f75a --- /dev/null +++ b/backend/ModernWMS.Core/JWT/ClaimValueTypes.cs @@ -0,0 +1,13 @@ +namespace ModernWMS.Core.JWT +{ + /// + /// JWT custom type + /// + public static class ClaimValueTypes + { + /// + /// JSON + /// + public const string Json = "json"; + } +} diff --git a/backend/ModernWMS.Core/JWT/CurrentUser.cs b/backend/ModernWMS.Core/JWT/CurrentUser.cs new file mode 100644 index 0000000..dc32b03 --- /dev/null +++ b/backend/ModernWMS.Core/JWT/CurrentUser.cs @@ -0,0 +1,34 @@ +using System.ComponentModel.DataAnnotations; +using System.Xml.Linq; + +namespace ModernWMS.Core.JWT +{ + /// + /// CurrentUser + /// + public class CurrentUser + { + /// + /// user_id + /// + public int user_id { get; set; } = 1; + /// + /// user_num + /// + public string user_num { get; set; } = "admin"; + /// + /// user_name + /// + public string user_name { get; set; } = "admin"; + + /// + /// user_role + /// + public string user_role { get; set; } = "admin"; + + /// + /// tenant + /// + public long tenant_id { get; set; } = 1; + } +} diff --git a/backend/ModernWMS.Core/JWT/ITokenManager.cs b/backend/ModernWMS.Core/JWT/ITokenManager.cs new file mode 100644 index 0000000..622b3c0 --- /dev/null +++ b/backend/ModernWMS.Core/JWT/ITokenManager.cs @@ -0,0 +1,36 @@ + +namespace ModernWMS.Core.JWT +{ + /// + /// token manager interface + /// + public interface ITokenManager + { + /// + /// Method of generating AccessToken + /// + /// userClaims + /// + (string token, int expire) GenerateToken(CurrentUser userClaims); + /// + /// Method of refreshing token + /// + /// + string GenerateRefreshToken(); + /// + /// Get the minutes of refreshed token invalidation + /// + /// + int GetRefreshTokenExpireMinute(); + /// + /// Get the current user information in the token + /// + /// + CurrentUser GetCurrentUser(); + /// + /// Get the current user information in the token + /// + /// + CurrentUser GetCurrentUser(string token); + } +} diff --git a/backend/ModernWMS.Core/JWT/TokenManager.cs b/backend/ModernWMS.Core/JWT/TokenManager.cs new file mode 100644 index 0000000..b34ea1a --- /dev/null +++ b/backend/ModernWMS.Core/JWT/TokenManager.cs @@ -0,0 +1,182 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Claims; +using System.Security.Cryptography; +using System.Text; +using ModernWMS.Core.Utility; + +namespace ModernWMS.Core.JWT +{ + /// + /// token manager + /// + public class TokenManager : ITokenManager + { + private readonly IOptions _tokenSettings;//token setting + private readonly IHttpContextAccessor _accessor; // Inject IHttpContextAccessor + /// + /// Constructor + /// + /// token setting s + /// Inject IHttpContextAccessor + public TokenManager(IOptions tokenSettings + , IHttpContextAccessor accessor) + { + this._tokenSettings = tokenSettings; + this._accessor = accessor; + } + /// + /// Method of refreshing token + /// + /// + public string GenerateRefreshToken() + { + var randomNumber = new byte[32]; + + using (var rng = RandomNumberGenerator.Create()) + { + rng.GetBytes(randomNumber); + + return Convert.ToBase64String(randomNumber); + } + } + /// + /// Method of generating AccessToken + /// + /// 自定义信息 + /// (token,有效分钟数) + public (string token, int expire) GenerateToken(CurrentUser userClaims) + { + string token = new JwtSecurityTokenHandler().WriteToken(new JwtSecurityToken( + issuer: _tokenSettings.Value.Issuer, + audience: _tokenSettings.Value.Audience, + claims: SetClaims(userClaims), + expires: DateTime.Now.AddMinutes(_tokenSettings.Value.ExpireMinute), + signingCredentials: new SigningCredentials( + new SymmetricSecurityKey(Encoding.UTF8.GetBytes(GlobalConsts.SigningKey)), + SecurityAlgorithms.HmacSha256) + )); + + return (token, _tokenSettings.Value.ExpireMinute); + } + /// + /// Get the current user information in the token + /// + /// + public CurrentUser GetCurrentUser() + { + if (_accessor.HttpContext == null) + { + return new CurrentUser(); + } + var token = _accessor.HttpContext.Request.Headers["Authorization"].ObjToString(); + if (!token.StartsWith("Bearer")) + { + return new CurrentUser(); + } + token = token.Replace("Bearer ", ""); + if (token.Length > 0) + { + var principal = new JwtSecurityTokenHandler().ValidateToken(token, + new TokenValidationParameters + { + ValidateAudience = false, + ValidateIssuer = false, + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(GlobalConsts.SigningKey)), + ValidateLifetime = false + }, + out var securityToken); + + if (!(securityToken is JwtSecurityToken jwtSecurityToken) || + !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase)) + { + return new CurrentUser(); + } + var user = JsonHelper.DeserializeObject(principal.Claims.First(claim => claim.Type == ClaimValueTypes.Json).Value); + if (user != null) + { + return user; + } + else + { + return new CurrentUser(); + } + } + else + { + return new CurrentUser(); + } + + } + + /// + /// Get the current user information in the token + /// + /// + public CurrentUser GetCurrentUser(string token) + { + if (token.Length > 0) + { + var principal = new JwtSecurityTokenHandler().ValidateToken(token, + new TokenValidationParameters + { + ValidateAudience = false, + ValidateIssuer = false, + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(GlobalConsts.SigningKey)), + ValidateLifetime = false + }, + out var securityToken); + + if (!(securityToken is JwtSecurityToken jwtSecurityToken) || + !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase)) + { + return new CurrentUser(); + } + var user = JsonHelper.DeserializeObject(principal.Claims.First(claim => claim.Type == ClaimValueTypes.Json).Value); + if (user != null) + { + return user; + } + else + { + return new CurrentUser(); + } + } + else + { + return new CurrentUser(); + } + + } + /// + /// Method of refreshing token + /// + /// + public int GetRefreshTokenExpireMinute() + { + return _tokenSettings.Value.ExpireMinute + 1; + } + + /// + /// Setting Custom Information + /// + /// Custom Information + /// + private static IEnumerable SetClaims(CurrentUser userClaims) + { + return new List + { + new Claim(ClaimTypes.Sid, Guid.NewGuid().ToString()), + new Claim(ClaimValueTypes.Json,JsonHelper.SerializeObject(userClaims), ClaimValueTypes.Json) + }; + } + + } +} diff --git a/backend/ModernWMS.Core/JWT/TokenSettings.cs b/backend/ModernWMS.Core/JWT/TokenSettings.cs new file mode 100644 index 0000000..86ce2f2 --- /dev/null +++ b/backend/ModernWMS.Core/JWT/TokenSettings.cs @@ -0,0 +1,26 @@ + +namespace ModernWMS.Core.JWT +{ + /// + /// token settings + /// + public class TokenSettings + { + /// + /// Audience + /// + public string Audience { get; set; } + /// + /// Issuer + /// + public string Issuer { get; set; } + /// + /// SigningKey + /// + public string SigningKey { get; set; } + /// + /// Expire + /// + public int ExpireMinute { get; set; } + } +} diff --git a/backend/ModernWMS.Core/Middleware/CorsMiddleware.cs b/backend/ModernWMS.Core/Middleware/CorsMiddleware.cs new file mode 100644 index 0000000..ae6163c --- /dev/null +++ b/backend/ModernWMS.Core/Middleware/CorsMiddleware.cs @@ -0,0 +1,61 @@ +using Microsoft.AspNetCore.Http; +using System.Threading.Tasks; + +namespace ModernWMS.Core.Middleware +{ + /// + /// Cross domain middleware + /// + public class CorsMiddleware + { + #region parameter + /// + /// agent + /// + private readonly RequestDelegate _next; + #endregion + + #region Constructor + + /// + /// Constructor + /// + /// Delegate in next step + public CorsMiddleware(RequestDelegate next) + { + _next = next; + } + #endregion + + /// + /// Invoke + /// + /// httpContext + /// + public Task Invoke(HttpContext httpContext) + { + + if (httpContext.Request.Method == "OPTIONS") + { + httpContext.Response.Headers.Add("Access-Control-Allow-Origin", httpContext.Request.Headers["Origin"]); + httpContext.Response.Headers.Add("Access-Control-Allow-Headers", httpContext.Request.Headers["Access-Control-Request-Headers"]); + httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS,HEAD,PATCH"); + httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true"); + httpContext.Response.Headers.Add("Access-Control-Max-Age", "86400"); + httpContext.Response.StatusCode = StatusCodes.Status200OK; + return Task.CompletedTask; + } + if (httpContext.Request.Headers["Origin"] != "") + { + httpContext.Response.Headers.Add("Access-Control-Allow-Origin", httpContext.Request.Headers["Origin"]); + } + + httpContext.Response.Headers.Add("Access-Control-Allow-Headers", httpContext.Request.Headers["Access-Control-Request-Headers"]); + httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS,HEAD,PATCH"); + httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true"); + httpContext.Response.Headers.Add("Access-Control-Max-Age", "86400"); + return _next.Invoke(httpContext); + } + + } +} diff --git a/backend/ModernWMS.Core/Middleware/GlobalExceptionMiddleware.cs b/backend/ModernWMS.Core/Middleware/GlobalExceptionMiddleware.cs new file mode 100644 index 0000000..9df3b26 --- /dev/null +++ b/backend/ModernWMS.Core/Middleware/GlobalExceptionMiddleware.cs @@ -0,0 +1,105 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using System; +using System.Linq; +using System.Threading.Tasks; +using ModernWMS.Core.Models; +using Microsoft.Extensions.Localization; + +namespace ModernWMS.Core.Middleware +{ + /// + /// Global exception middleware + /// + public class GlobalExceptionMiddleware + { + #region parameter + private readonly RequestDelegate next; + private readonly ILogger logger; + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region Constructor + /// + /// Constructor + /// + /// Delegate in next step + /// log manager + /// Localizer + public GlobalExceptionMiddleware(RequestDelegate next, + ILogger logger, + IStringLocalizer stringLocalizer + ) + { + this.next = next; + this.logger = logger; + this._stringLocalizer = stringLocalizer; + } + #endregion + + /// + /// invoke + /// + /// httpcontext + /// + public async Task Invoke(HttpContext context) + { + try + { + await next.Invoke(context); + } + catch (Exception ex) + { + await WriteExceptionAsync(context, ex); + } + } + /// + /// Write Log + /// + /// httpcontext + /// error messasge + /// + private async Task WriteExceptionAsync(HttpContext context, Exception e) + { + if (e != null) + { + var response = context.Response; + var message = e.InnerException == null ? e.Message : e.InnerException.Message; + response.ContentType = "application/json"; + + var ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault(); + if (string.IsNullOrEmpty(ip)) + { + ip = context.Connection.RemoteIpAddress.ToString(); + } + logger.LogError($"\r\n\r\nIP:{ip},Exception:{e.Message}\r\nStackTrace:{e.StackTrace}"); + + string result = Utility.JsonHelper.SerializeObject(ResultModel.Error(_stringLocalizer["operation_failed"])); + await context.Response.WriteAsync(result).ConfigureAwait(false); + } + else + { + var code = context.Response.StatusCode; + switch (code) + { + case 200: + return; + case 204: + return; + case 401: + context.Response.ContentType = "application/json"; + await context.Response.WriteAsync(Utility.JsonHelper.SerializeObject(ResultModel.Error("Invalid Token"))).ConfigureAwait(false); + break; + default: + context.Response.ContentType = "application/json"; + await context.Response.WriteAsync(Utility.JsonHelper.SerializeObject(ResultModel.Error("Unknown Error"))).ConfigureAwait(false); + break; + } + } + } + + } +} diff --git a/backend/ModernWMS.Core/Middleware/RequestResponseMiddleware.cs b/backend/ModernWMS.Core/Middleware/RequestResponseMiddleware.cs new file mode 100644 index 0000000..f50ec3e --- /dev/null +++ b/backend/ModernWMS.Core/Middleware/RequestResponseMiddleware.cs @@ -0,0 +1,138 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using ModernWMS.Core.Models; + +namespace ModernWMS.Core.Middleware +{ + /// + /// Request response middleware + /// + public class RequestResponseMiddleware + { + #region parameter + /// + /// Delegate + /// + private readonly RequestDelegate _next; + /// + /// log manager + /// + private readonly ILogger _logger; + + #endregion + + #region Constructor + /// + /// Constructor + /// + /// Delegate + /// log manager + public RequestResponseMiddleware(RequestDelegate next + , ILogger logger) + { + _next = next; + _logger = logger; + } + + #endregion + + /// + /// Invoke + /// + /// httpcontext + /// + public async Task Invoke(HttpContext context) + { + if (ModernWMS.Core.Utility.GlobalConsts.IsRequestResponseMiddleware) + { + string requestInfo = "", responseInfo = ""; + var originalBodyStream = context.Response.Body; + var stopwach = Stopwatch.StartNew(); + try + { + + requestInfo = await FormatRequest(context.Request); + + using (var responseBody = new MemoryStream()) + { + context.Response.Body = responseBody; + + await _next(context); + stopwach.Stop(); + + responseInfo = await FormatResponse(context.Response); + + await responseBody.CopyToAsync(originalBodyStream); + } + + + var logMsg = $@"request information: {requestInfo} ;time spent: {stopwach.ElapsedMilliseconds}ms"; + _logger.LogInformation(logMsg); + + } + catch (Exception ex) + { + stopwach.Stop(); + if (ex != null) + { + var logMsg = $@"request information: {requestInfo}{Environment.NewLine}exception: {ex.ToString()}{Environment.NewLine}time spent: {stopwach.ElapsedMilliseconds}ms"; + + _logger.LogError(logMsg); + _logger.LogError(ex.ToString()); + + string result = Utility.JsonHelper.SerializeObject(ResultModel.Error(ex.Message)); + var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(result)); + await originalBodyStream.WriteAsync(bytes, 0, bytes.Length); + + } + } + + + } + else + { + await _next(context); + } + + + } + /// + /// format request + /// + /// request + /// + private async Task FormatRequest(HttpRequest request) + { + HttpRequestRewindExtensions.EnableBuffering(request); + var body = request.Body; + + var buffer = new byte[Convert.ToInt32(request.ContentLength)]; + await request.Body.ReadAsync(buffer, 0, buffer.Length); + var bodyAsText = Encoding.UTF8.GetString(buffer); + body.Seek(0, SeekOrigin.Begin); + request.Body = body; + + return $" {request.Method} {request.Scheme}://{request.Host}{request.Path} {request.QueryString} {bodyAsText}"; + } + /// + /// format response + /// + /// response + /// + private async Task FormatResponse(HttpResponse response) + { + response.Body.Seek(0, SeekOrigin.Begin); + var text = await new StreamReader(response.Body).ReadToEndAsync(); + response.Body.Seek(0, SeekOrigin.Begin); + + return $"{response.StatusCode}: {text}"; + } + + } +} diff --git a/backend/ModernWMS.Core/Middleware/ViewModelActionFiter.cs b/backend/ModernWMS.Core/Middleware/ViewModelActionFiter.cs new file mode 100644 index 0000000..979fe13 --- /dev/null +++ b/backend/ModernWMS.Core/Middleware/ViewModelActionFiter.cs @@ -0,0 +1,78 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using ModernWMS.Core.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.Core.Middleware +{ + /// + /// ViewModelActionFiter + /// + public class ViewModelActionFiter : ActionFilterAttribute + { + /// + /// override OnActionExecuting + /// + /// context + public override void OnActionExecuting(ActionExecutingContext context) + { + + if (!context.ModelState.IsValid) + { + string method = context.HttpContext.Request.Method; + ResultModel result = new ResultModel(); + StringBuilder msg = new StringBuilder(); + bool flag = false; + foreach (var item in context.ModelState.Values) + { + if (method.Equals("GET")) + { + msg.Append($",parameter value“{item.AttemptedValue}”does not pass the verification!"); + } + else + { + foreach (var error in item.Errors) + { + if (error.ErrorMessage.Contains("convert") + || error.ErrorMessage.Contains("Unexpected character") + || error.ErrorMessage.Contains("is not") + || error.ErrorMessage.Contains("valid") + || error.ErrorMessage.Contains("Input ")) + { + flag = true; + } + else + { + msg.Append($",{error.ErrorMessage}"); + } + } + } + } + if (flag) + { + msg.Append($",The data is of incorrect type or the value exceeds the type range"); + } + if (msg.ToString().Length > 0) + { + result.ErrorMessage += msg.ToString().Substring(1); + } + result.Code = 400; + context.Result = new JsonResult(result, new Newtonsoft.Json.JsonSerializerSettings() + { + ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(), + Formatting = Newtonsoft.Json.Formatting.Indented, + DateFormatString = "yyyy-MM-dd HH:mm:ss" + }); + } + else + { + base.OnActionExecuting(context); + } + + } + } +} diff --git a/backend/ModernWMS.Core/Models/BaseModel.cs b/backend/ModernWMS.Core/Models/BaseModel.cs new file mode 100644 index 0000000..1a29aa2 --- /dev/null +++ b/backend/ModernWMS.Core/Models/BaseModel.cs @@ -0,0 +1,16 @@ + +using System; +using System.ComponentModel.DataAnnotations; +namespace ModernWMS.Core.Models +{ + [Serializable] + public abstract class BaseModel + { + /// + /// id + /// + [Key] + public int id { get; set; } = 0; + + } +} diff --git a/backend/ModernWMS.Core/Models/BatchOperationViewModel.cs b/backend/ModernWMS.Core/Models/BatchOperationViewModel.cs new file mode 100644 index 0000000..4b3a280 --- /dev/null +++ b/backend/ModernWMS.Core/Models/BatchOperationViewModel.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.Core.Models +{ + public class BatchOperationViewModel + { + public List id_list { get; set; } = new List(); + } +} diff --git a/backend/ModernWMS.Core/Models/FormSelectItem.cs b/backend/ModernWMS.Core/Models/FormSelectItem.cs new file mode 100644 index 0000000..5085bc8 --- /dev/null +++ b/backend/ModernWMS.Core/Models/FormSelectItem.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.Core.Models +{ + /// + /// select items model + /// + public class FormSelectItem + { + /// + /// key + /// + public string code { get; set; } = string.Empty; + /// + /// comment + /// + public string comments { get; set; } = string.Empty; + + /// + /// text + /// + public string name { get; set; } = string.Empty; + /// + /// value + /// + public string value { get; set; } = string.Empty; + } +} diff --git a/backend/ModernWMS.Core/Models/LoginInputViewModel.cs b/backend/ModernWMS.Core/Models/LoginInputViewModel.cs new file mode 100644 index 0000000..03b1705 --- /dev/null +++ b/backend/ModernWMS.Core/Models/LoginInputViewModel.cs @@ -0,0 +1,25 @@ + +using System.ComponentModel.DataAnnotations; +using System.Collections.Generic; +namespace ModernWMS.Core.Models +{ + /// + /// login input viewmodel + /// + public class LoginInputViewModel + { + /// + /// username + /// + [Required(ErrorMessage ="Required")] + [Display(Name = "user_name")] + public string user_name { get; set; } = string.Empty; + /// + /// password + /// + + [Required(ErrorMessage ="Required")] + [Display(Name = "password")] + public string password { get; set; } = string.Empty; + } +} diff --git a/backend/ModernWMS.Core/Models/LoginOutputViewModel.cs b/backend/ModernWMS.Core/Models/LoginOutputViewModel.cs new file mode 100644 index 0000000..475b060 --- /dev/null +++ b/backend/ModernWMS.Core/Models/LoginOutputViewModel.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; + +namespace ModernWMS.Core.Models +{ + /// + /// LoginOutputViewModel + /// + public class LoginOutputViewModel + { + /// + /// user's num + /// + public string user_num { get; set; } + + /// + /// user's name + /// + public string user_name { get; set; } + + /// + /// user's id + /// + public int user_id { get; set; } + + /// + /// user's role + /// + public string user_role { get; set; } + + /// + /// id of user's role + /// + public int userrole_id { get; set; } + + /// + /// tenant_id + /// + public long tenant_id { get; set; } + + /// + /// token expire time + /// + public int expire { get; set; } + + /// + /// token + /// + public string access_token { get; set; } + + /// + /// refresh token + /// + public string refresh_token { get; set; } + + } +} diff --git a/backend/ModernWMS.Core/Models/MultiLanguage.cs b/backend/ModernWMS.Core/Models/MultiLanguage.cs new file mode 100644 index 0000000..bf0c1d7 --- /dev/null +++ b/backend/ModernWMS.Core/Models/MultiLanguage.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.Core +{ + public class MultiLanguage + { + } +} diff --git a/backend/ModernWMS.Core/Models/MultiLanguage.en-us.resx b/backend/ModernWMS.Core/Models/MultiLanguage.en-us.resx new file mode 100644 index 0000000..4f79028 --- /dev/null +++ b/backend/ModernWMS.Core/Models/MultiLanguage.en-us.resx @@ -0,0 +1,636 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + carrier + + + Departure City + + + Arrival City + + + Weight Fee + + + Volume Fee + + + Min Payment + + + Creator + + + Create Time + + + Last Update Time + + + Valid + + + User Num + + + User Name + + + Role + + + Contact Information + + + Sex + + + Warehouse Setting + + + Reservoir Setting + + + Location Setting + + + Location Select Modal + + + Email + + + Warehouse Name + + + City + + + Address + + + Manager + + + Reservoir Name + + + Reservoir Category + + + Location Code + + + Location Length + + + Location Width + + + Location Height + + + Location Volume + + + Location Load + + + Roadway Number + + + Shelf Number + + + Layer Number + + + Tag Number + + + Picking Area + + + Stocking Area + + + Receiving Area + + + Return Area + + + Defective Area + + + Inventory Area + + + Customer Name + + + Supplier Name + + + User Role + + + Corporate Name + + + Owner Of Cargo + + + Commodity category + + + Parent Category + + + Menu Name + + + Commodity Code + + + Commodity Name + + + Specification Code + + + Specification Name + + + Commodity Description + + + Specification Code + + + Brand + + + Commodity Unit + + + Commodity Cost + + + Commodity Price + + + origin + + + Length Unit + + + Volume Unit + + + Weight Unit + + + Commodity Weight + + + Commodity Length + + + Commodity Width + + + Commodity Height + + + Commodity Volume + + + Warehouse Name + + + Available Qty + + + Job Code + + + Job Type + + + Process Status + + + Processor + + + Process Time + + + Quantity + + + Is Source + + + Target Warehouse + + + Target Location + + + Is Updated Stock + + + Is Updated Stock + + + Source + + + Target + + + Move Status + + + Handler + + + Handle Time + + + Origin Warehouse + + + Origin Location + + + Target Warehouse + + + Target Location + + + Freeze + + + Unfreeze + + + Job Status + + + Book Qty + + + Actual Qty + + + Difference Qty + + + Confirm Taking + + + Stock Location + + + Stock + + + Sku Id + + + Locked Quantity + + + Frozen Quantity + + + Asn Quantity + + + Unload Quantity + + + Sort Quantity + + + Sorted Quantity + + + Shortage Quantity + + + ID + + + Asn No + + + Asn Status + + + Spu Id + + + Asn Quantity + + + Actual Quantity + + + Sorted Quantity + + + More Quantity + + + Damage Quantity + + + Supplier Id + + + Goods Owner Id + + + Invoice + + + Pre Shipment + + + New Shipment + + + Goods To Be Picked + + + Picked + + + To Be Packaged + + + Pack + + + Packaged + + + To Be Weighed + + + Weigh + + + Weighed + + + Delivery + + + To Be Delivered + + + Out Of Warehouse + + + Sign In + + + Signed In + + + Shipment No + + + Shipment Doc Status + + + Quantity + + + The data has changed.Please refresh and retry the operation + + + Delete failed + + + The data has been referenced and cannot be deleted + + + Delete success + + + The {0}:{1} is exists + + + The data does not exist or has been deleted + + + {0} input length must less than or equal {1} + + + Operation failed + + + Operation succeeded + + + {0} is Required + + + Failure + + + Success + + + The status of this data has changed.Please refresh and retry the operation + + + Current status cannot be deleted + + + The ASN status is not PreDelivery + + + The ASN status is not PreLoad + + + The ASN status is not PreSort + + + The ASN status is not Sorted + + + The ASN status is not Sorting + + + The ASN status is putaway + + + The ASN putaway's quantity greater than sorted quantity + + + Putaway success + + + Putaway failed + + + Sorted success + + + Sorted failed + + + The current operation cannot be performed. Please refresh and try again + + + Unpacked quantity is less than the quantity to be packed.Please refresh and try again + + + Unweighed quantity is less than the quantity to be weighed.Please refresh and try again + + + Login failed + + + The warehouse location has been set under this warehouse area and cannot be deleted + + + The warehouse area has been set under this warehouse and cannot be deleted + + + There are un issued shipment documents + + + There are unconfirmed inventory movements in this location + + + There are unconfirmed warehouse processings + + \ No newline at end of file diff --git a/backend/ModernWMS.Core/Models/MultiLanguage.zh-cn.resx b/backend/ModernWMS.Core/Models/MultiLanguage.zh-cn.resx new file mode 100644 index 0000000..7658a41 --- /dev/null +++ b/backend/ModernWMS.Core/Models/MultiLanguage.zh-cn.resx @@ -0,0 +1,636 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 承运商 + + + 始发城市 + + + 到货城市 + + + 单公斤运费 + + + 单立方米运费 + + + 最小运费 + + + 创建人 + + + 创建时间 + + + 最后更新时间 + + + 是否有效 + + + 员工编号 + + + 员工名称 + + + 角色 + + + 联系方式 + + + 性别 + + + 仓库设置 + + + 库区设置 + + + 库位设置 + + + 库位选择框 + + + Email + + + 仓库名称 + + + 所在城市 + + + 详细地址 + + + 负责人 + + + 库区名称 + + + 库区类型 + + + 库位编码 + + + 库位长 + + + 库位宽 + + + 库位高 + + + 库位容积 + + + 库位承重 + + + 巷道号 + + + 货架号 + + + 层号 + + + 位号 + + + 拣货区 + + + 备货区 + + + 收货区 + + + 退货区 + + + 次品区 + + + 存货区 + + + 客户名称 + + + 供应商名称 + + + 用户角色 + + + 公司名称 + + + 货主名称 + + + 商品类别 + + + 所属类别 + + + 菜单名称 + + + 商品编码 + + + 商品名称 + + + 规格编码 + + + 规格名称 + + + 商品描述 + + + 商品条码 + + + 品牌 + + + 商品单位 + + + 商品成本 + + + 商品价格 + + + 产地 + + + 长度单位 + + + 体积单位 + + + 重量单位 + + + 商品重量 + + + 商品长度 + + + 商品宽度 + + + 商品高度 + + + 商品体积 + + + 仓库名称 + + + 可用数量 + + + 作业单号 + + + 作业类型 + + + 加工状态 + + + 操作人 + + + 操作时间 + + + 数量 + + + 是否来源商品 + + + 目标仓库 + + + 目标库位 + + + 是否已更新库存 + + + 是否已调整 + + + 来源 + + + 目标 + + + 作业状态 + + + 操作人 + + + 操作时间 + + + 来源仓库 + + + 来源库位 + + + 目标仓库 + + + 目标库位 + + + 冻结 + + + 解冻 + + + 作业状态 + + + 账面数量 + + + 盘点数量 + + + 差异数量 + + + 确认盘点 + + + 库位列表 + + + 库存列表 + + + 规格标识 + + + 锁定数量 + + + 冻结数量 + + + 到货通知书数量 + + + 待卸货数量 + + + 待分拣数量 + + + 已分拣数量 + + + 欠货数量 + + + 标识 + + + 到货通知书编号 + + + 到货通知书状态 + + + 商品spu标识 + + + 到货通知书数据 + + + 上架数量 + + + 分拣数量 + + + 超量数量 + + + 破损数量 + + + 供应商标识 + + + 货主标识 + + + 发货单 + + + 预发货 + + + 新发货 + + + 待拣货 + + + 已拣货 + + + 待打包 + + + 打包 + + + 已打包 + + + 待称重 + + + 称重 + + + 已称重 + + + 出库 + + + 待出库 + + + 已出库 + + + 签收 + + + 已签收 + + + 发货单号 + + + 发货单状态 + + + 数量 + + + 数据发生改变,请刷新后重试操作 + + + 删除失败 + + + 数据已被引用,不能删除 + + + 删除成功 + + + {0}:{1} 已经存在 + + + 数据不存在或已被删除 + + + {0}输入字符长度不能大于{1}个字符 + + + 操作失败 + + + 操作成功 + + + {0}必填 + + + 保存失败 + + + 保存成功 + + + 当前状态已改变,请刷新后重试 + + + 当前状态不可删除 + + + ASN 状态不是待到货 + + + ASN 状态不是待卸货 + + + ASN 状态不是待分拣 + + + ASN 状态不是已分拣 + + + ASN 尚未分拣 + + + ASN 已经上架 + + + ASN 上架数量超过了分拣数量 + + + 上架成功 + + + 上架失败 + + + 确认分拣完成成功 + + + 确认分拣完成失败 + + + 不能进行当前操作,请刷新后重试 + + + 未打包数量小于当前操作打包数量,请刷新后重试 + + + 未称重数量小于当前操作称重数量,请刷新后重试 + + + 登录失败 + + + 该库位存在未出库的发货单 + + + 该库区下已设置库位,不能删除 + + + 该仓库下已设置库区,不能删除 + + + 该库位存在未确认的库存移动 + + + 该库位存在未确认的仓内加工 + + \ No newline at end of file diff --git a/backend/ModernWMS.Core/Models/PageData.cs b/backend/ModernWMS.Core/Models/PageData.cs new file mode 100644 index 0000000..a53ba6f --- /dev/null +++ b/backend/ModernWMS.Core/Models/PageData.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.Core.Models +{ + /// + /// PageData + /// + /// + public class PageData + { + /// + /// data + /// + public List Rows { get; set; } = new List(2); + /// + /// total rows + /// + public int Totals { get; set; } = 0; + } +} diff --git a/backend/ModernWMS.Core/Models/PageSearch.cs b/backend/ModernWMS.Core/Models/PageSearch.cs new file mode 100644 index 0000000..d082e39 --- /dev/null +++ b/backend/ModernWMS.Core/Models/PageSearch.cs @@ -0,0 +1,30 @@ +using ModernWMS.Core.DynamicSearch; + +namespace ModernWMS.Core.Models +{ + /// + /// PageSearch + /// + public class PageSearch + { + /// + /// current page number + /// + public int pageIndex { get; set; } = 1; + + /// + /// rows per page + /// + public int pageSize { get; set; } = 20; + + /// + /// Custom Classification + /// + public string sqlTitle { get; set; } = ""; + + /// + /// search condition + /// + public List searchObjects { get; set; } = new List(); + } +} diff --git a/backend/ModernWMS.Core/Models/RefreshTokenInPutViewModel.cs b/backend/ModernWMS.Core/Models/RefreshTokenInPutViewModel.cs new file mode 100644 index 0000000..7957e92 --- /dev/null +++ b/backend/ModernWMS.Core/Models/RefreshTokenInPutViewModel.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.Core.Models +{ + /// + /// RefreshTokenInPutViewModel + /// + public class RefreshTokenInPutViewModel + { + /// + /// old access token + /// + [Required(ErrorMessage = "AccessToken is Required")] + public string AccessToken { get; set; } + /// + /// refresh token + /// + [Required(ErrorMessage = "RefreshToken is Required")] + public string RefreshToken { get; set; } + + } +} diff --git a/backend/ModernWMS.Core/Models/ResultModel.cs b/backend/ModernWMS.Core/Models/ResultModel.cs new file mode 100644 index 0000000..c75f234 --- /dev/null +++ b/backend/ModernWMS.Core/Models/ResultModel.cs @@ -0,0 +1,51 @@ +namespace ModernWMS.Core.Models +{ + /// + /// http response viewmodel + /// + public class ResultModel + { + /// + /// is request success + /// + public bool IsSuccess { get; set; } + /// + /// status code + /// + public int Code { get; set; } + /// + /// error message + /// + public string ErrorMessage { get; set; } = ""; + /// + /// data + /// + public T Data { get; set; } + + /// + /// success + /// + /// data + /// error message + /// + public static ResultModel Success(T data, string errMsg = "") + { + if (data == null) + { + return Error("Some errors have occurred"); + } + return new ResultModel { Data = data, ErrorMessage = errMsg, IsSuccess = true, Code = 200 }; + } + /// + /// faild + /// + /// error message + /// status code + /// data + /// + public static ResultModel Error(string str, int code = 400, T data = default) + { + return new ResultModel { Data = data, ErrorMessage = str, IsSuccess = false, Code = code }; + } + } +} diff --git a/backend/ModernWMS.Core/Models/UserroleEntity.cs b/backend/ModernWMS.Core/Models/UserroleEntity.cs new file mode 100644 index 0000000..4cc532c --- /dev/null +++ b/backend/ModernWMS.Core/Models/UserroleEntity.cs @@ -0,0 +1,52 @@ +/* + * date:2022-12-20 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.Core.Models +{ + /// + /// userrole entity + /// + [Table("userrole")] + public class UserroleEntity : BaseModel + { + + #region Property + + /// + /// role_name + /// + public string role_name { get; set; } = string.Empty; + + /// + /// is_valid + /// + public bool is_valid { get; set; } = false; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.Core/Models/userEntity.cs b/backend/ModernWMS.Core/Models/userEntity.cs new file mode 100644 index 0000000..3b342b5 --- /dev/null +++ b/backend/ModernWMS.Core/Models/userEntity.cs @@ -0,0 +1,83 @@ +using Microsoft.AspNetCore.Mvc.RazorPages; +using ModernWMS.Core.Utility; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ModernWMS.Core.Models +{ + /// + /// user entity + /// + [Table("user")] + public class userEntity : BaseModel + { + + #region property + + /// + /// user's number + /// + public string user_num { get; set; } = string.Empty; + + /// + /// user's name + /// + public string user_name { get; set; } = string.Empty; + + /// + /// contact + /// + public string contact_tel { get; set; } = string.Empty; + + /// + /// user's role + /// + public string user_role { get; set; } = string.Empty; + + /// + /// sex + /// + public string sex { get; set; } = string.Empty; + + /// + /// is_valid + /// + public bool is_valid { get; set; } = false; + + /// + /// password + /// + public string auth_string { get; set; } = string.Empty; + + /// + /// email + /// + public string email { get; set; } = string.Empty; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// createtime + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last update time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant + /// + public long tenant_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.Core/ModernWMS.Core.csproj b/backend/ModernWMS.Core/ModernWMS.Core.csproj new file mode 100644 index 0000000..cd4737c --- /dev/null +++ b/backend/ModernWMS.Core/ModernWMS.Core.csproj @@ -0,0 +1,53 @@ + + + + net7.0 + enable + enable + True + + + + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + Always + + + + diff --git a/backend/ModernWMS.Core/MultiTenancy/ITenantProvider.cs b/backend/ModernWMS.Core/MultiTenancy/ITenantProvider.cs new file mode 100644 index 0000000..2cece78 --- /dev/null +++ b/backend/ModernWMS.Core/MultiTenancy/ITenantProvider.cs @@ -0,0 +1,14 @@ +namespace ModernWMS.Core.MultiTenancy +{ + /// + /// TenantProvider + /// + public interface ITenantProvider + { + /// + /// Get Current User's TenantID + /// + /// + byte GetCurrentTenantID(); + } +} diff --git a/backend/ModernWMS.Core/MultiTenancy/Tenant.cs b/backend/ModernWMS.Core/MultiTenancy/Tenant.cs new file mode 100644 index 0000000..dd77967 --- /dev/null +++ b/backend/ModernWMS.Core/MultiTenancy/Tenant.cs @@ -0,0 +1,17 @@ +namespace ModernWMS.Core.MultiTenancy +{ + /// + /// Tenant Class + /// + public class Tenant + { + /// + /// tenant's id + /// + public byte tenant_id { get; set; } = 1; + /// + /// tenant's name + /// + public string tenant_name { get; set; } = "default"; + } +} diff --git a/backend/ModernWMS.Core/MultiTenancy/TenantProvider.cs b/backend/ModernWMS.Core/MultiTenancy/TenantProvider.cs new file mode 100644 index 0000000..5521def --- /dev/null +++ b/backend/ModernWMS.Core/MultiTenancy/TenantProvider.cs @@ -0,0 +1,46 @@ +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; +using System.Text; +using System.Linq; + +namespace ModernWMS.Core.MultiTenancy +{ + /// + /// TenantProvider + /// + public class TenantProvider:ITenantProvider + { + /// + /// Tenant + /// + private readonly Tenant tenant; + /// + /// TenantProvider + /// + /// 注入IHttpContextAccessor + public TenantProvider(IHttpContextAccessor accessor) + { + if (accessor.HttpContext != null) + { + var headers = accessor.HttpContext.Request.Headers; + if (headers != null && headers.Count > 0 + && headers.ContainsKey("TenantName")) + { + var name = headers["TenantName"].FirstOrDefault(); + } + } + //Default Value + tenant = new Tenant(); + } + + /// + /// Get Current User's TenantID + /// + /// + public byte GetCurrentTenantID() + { + return tenant.tenant_id; + } + } +} diff --git a/backend/ModernWMS.Core/Services/AccountService.cs b/backend/ModernWMS.Core/Services/AccountService.cs new file mode 100644 index 0000000..2fc35ec --- /dev/null +++ b/backend/ModernWMS.Core/Services/AccountService.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using ModernWMS.Core.Models; +using System.Linq; +using ModernWMS.Core.Utility; +using System.Data; +using Mapster; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Internal; +using ModernWMS.Core.DBContext; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.JWT; + +namespace ModernWMS.Core.Services +{ + /// + /// AccountService + /// + public class AccountService : IAccountService + { + private readonly SqlDBContext _sqlDBContext; + private readonly IStringLocalizer _stringLocalizer; + + public AccountService(SqlDBContext sqlDBContext, IStringLocalizer stringLocalizer +) + { + _sqlDBContext = sqlDBContext; + _stringLocalizer = stringLocalizer; + } + + /// + /// login + /// + /// login params viewmodel + /// current user + /// + public async Task Login(LoginInputViewModel loginInput, CurrentUser currentUser) + { + var users = await (from user in _sqlDBContext.GetDbSet().AsNoTracking() + join ur in _sqlDBContext.GetDbSet().AsNoTracking() on user.user_role equals ur.role_name + where ur.tenant_id == user.tenant_id&&(user.user_name == loginInput.user_name || user.user_num == loginInput.user_name) + select new { + user_id = user.id, + user_num = user.user_num, + user_name = user.user_name, + user_role = user.user_role, + userrole_id = ur.id, + cipher = user.auth_string, + tenant_id = user.tenant_id + } + ).ToListAsync(); + string md5_password = Core.Utility.Md5Helper.Md5Encrypt32(loginInput.password); + var result = users.FirstOrDefault(t=>t.cipher== md5_password || t.cipher == loginInput.password); + if(result!= null) + { + return new LoginOutputViewModel() + { + user_id = result.user_id, + user_name = result.user_name, + user_num = result.user_num, + user_role = result.user_role, + userrole_id = result.userrole_id, + tenant_id= result.tenant_id, + }; + } + return null; + } + + public string HelloWorld () + { + return _stringLocalizer["hello word"]; + } + + } + +} diff --git a/backend/ModernWMS.Core/Services/BaseService.cs b/backend/ModernWMS.Core/Services/BaseService.cs new file mode 100644 index 0000000..fd29334 --- /dev/null +++ b/backend/ModernWMS.Core/Services/BaseService.cs @@ -0,0 +1,18 @@ + +using Mapster; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using ModernWMS.Core.Models; +using Microsoft.Extensions.Localization; + +namespace ModernWMS.Core.Services +{ + public class BaseService : IBaseService where TEntity : BaseModel + { + + } +} diff --git a/backend/ModernWMS.Core/Services/IAccountService.cs b/backend/ModernWMS.Core/Services/IAccountService.cs new file mode 100644 index 0000000..b375e74 --- /dev/null +++ b/backend/ModernWMS.Core/Services/IAccountService.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; + +namespace ModernWMS.Core.Services +{ + /// + /// account service interface + /// + public interface IAccountService + { + + /// + /// login + /// + /// user 's account infomation + /// current user + /// + Task Login(LoginInputViewModel loginInput,CurrentUser currentUser); + + string HelloWorld(); + } +} diff --git a/backend/ModernWMS.Core/Services/IBaseService.cs b/backend/ModernWMS.Core/Services/IBaseService.cs new file mode 100644 index 0000000..e615a14 --- /dev/null +++ b/backend/ModernWMS.Core/Services/IBaseService.cs @@ -0,0 +1,16 @@ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using ModernWMS.Core.DI; +using ModernWMS.Core.Models; +namespace ModernWMS.Core.Services +{ + + public interface IBaseService : IDependency where TEntity : BaseModel + { + + } +} diff --git a/backend/ModernWMS.Core/Swagger/CustomApiVersion.cs b/backend/ModernWMS.Core/Swagger/CustomApiVersion.cs new file mode 100644 index 0000000..7488a90 --- /dev/null +++ b/backend/ModernWMS.Core/Swagger/CustomApiVersion.cs @@ -0,0 +1,25 @@ + + +namespace ModernWMS.Core.Swagger +{ + /// + /// custom version + /// + public class CustomApiVersion + { + /// + /// Api module + /// + public enum ApiVersions + { + /// + /// Base + /// + Base, + /// + /// WMS + /// + WMS + } + } +} diff --git a/backend/ModernWMS.Core/Swagger/SwaggerSettings.cs b/backend/ModernWMS.Core/Swagger/SwaggerSettings.cs new file mode 100644 index 0000000..b45f78b --- /dev/null +++ b/backend/ModernWMS.Core/Swagger/SwaggerSettings.cs @@ -0,0 +1,38 @@ + +using System.Collections.Generic; + +namespace ModernWMS.Core.Swagger +{ + /// + /// Swagger Settings + /// + public class SwaggerSettings + { + /// + /// SwaggerDoc Name + /// + public string Name { get; set; } + /// + /// OpenApiInfo Title + /// + public string ApiTitle { get; set; } + /// + /// OpenApiInfo Version + /// + public string ApiVersion { get; set; } + /// + /// OpenApiInfo Description + /// + public string Description { get; set; } + /// + /// Whether to turn on authorization verification + /// + public bool SecurityDefinition { get; set; } + + /// + /// Included XML documents + /// + public List XmlFiles { get; set; } + + } +} diff --git a/backend/ModernWMS.Core/Swagger/index.html b/backend/ModernWMS.Core/Swagger/index.html new file mode 100644 index 0000000..2c8b079 --- /dev/null +++ b/backend/ModernWMS.Core/Swagger/index.html @@ -0,0 +1,120 @@ + + + + + + + + + + %(DocumentTitle) + + + + + + %(HeadContent) + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + diff --git a/backend/ModernWMS.Core/Utility/GlobalConsts.cs b/backend/ModernWMS.Core/Utility/GlobalConsts.cs new file mode 100644 index 0000000..73eedce --- /dev/null +++ b/backend/ModernWMS.Core/Utility/GlobalConsts.cs @@ -0,0 +1,31 @@ +namespace ModernWMS.Core.Utility +{ + /// + /// global constant + /// + public static class GlobalConsts + { + + /// + /// is Swagger enable + /// + public static bool IsEnabledSwagger = true; + + /// + /// Is RequestResponseMiddleware enable + /// + public static bool IsRequestResponseMiddleware = true; + + /// + /// token cipher + /// + public const string SigningKey = "ModernWMS_SigningKey"; + + /// + /// Password will expire every 30 days from last password change. + /// + public static int PasswordExpireDays = 30; + + + } +} diff --git a/backend/ModernWMS.Core/Utility/JsonHelper.cs b/backend/ModernWMS.Core/Utility/JsonHelper.cs new file mode 100644 index 0000000..9549466 --- /dev/null +++ b/backend/ModernWMS.Core/Utility/JsonHelper.cs @@ -0,0 +1,63 @@ + +using System.Data; +using Newtonsoft.Json; + +namespace ModernWMS.Core.Utility +{ + /// + /// JSON Helper + /// + public static class JsonHelper + { + #region JSON Helper + + /// + /// Deserialize + /// + /// + /// + /// + public static T DeserializeObject(string json) where T : class + { + return JsonConvert.DeserializeObject(json); + } + + /// + /// Serialize + /// + /// data + /// + public static string SerializeObject(object obj) + { + return JsonConvert.SerializeObject(obj + , new JsonSerializerSettings() + { + ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(), + Formatting = Formatting.Indented, + DateFormatString = "yyyy-MM-dd HH:mm:ss" + }); + } + + /// + /// Serialize to DataTable + /// + /// data + /// "" + /// + public static string SerializeDataTable(DataTable table,bool replaceNullToEmpty = false) + { + string json = JsonConvert.SerializeObject(table + , new JsonSerializerSettings() + { + DateFormatString = "yyyy-MM-dd HH:mm:ss" + }); + if (replaceNullToEmpty) + { + json = json.Replace("null", "\"\""); + } + return json; + } + #endregion + + } +} diff --git a/backend/ModernWMS.Core/Utility/Md5Helper.cs b/backend/ModernWMS.Core/Utility/Md5Helper.cs new file mode 100644 index 0000000..8bc45e6 --- /dev/null +++ b/backend/ModernWMS.Core/Utility/Md5Helper.cs @@ -0,0 +1,32 @@ + +using System.Security.Cryptography; +using System.Text; + +namespace ModernWMS.Core.Utility +{ + /// + /// md5 Helper + /// + public static class Md5Helper + { + /// + /// 32bit UTF8 MD5 Encrypt + /// + /// 明文 + /// + public static string Md5Encrypt32(string plaintext) + { + string pwd = string.Empty; + if (!string.IsNullOrEmpty(plaintext) && !string.IsNullOrWhiteSpace(plaintext)) + { + MD5 md5 = MD5.Create(); + byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(plaintext)); + foreach (var item in s) + { + pwd = string.Concat(pwd, item.ToString("x2")); + } + } + return pwd; + } + } +} diff --git a/backend/ModernWMS.Core/Utility/ModelConvertHelper.cs b/backend/ModernWMS.Core/Utility/ModelConvertHelper.cs new file mode 100644 index 0000000..0a4c0c7 --- /dev/null +++ b/backend/ModernWMS.Core/Utility/ModelConvertHelper.cs @@ -0,0 +1,106 @@ + +using System; +using System.Collections.Generic; +using System.Data; +using System.Reflection; + +namespace ModernWMS.Core.Utility +{ + /// + /// dataTable convert to model + /// + /// model + public static class ModelConvertHelper where T : new() + { + /// + /// dataTable convert to model list + /// + /// 数据表 + /// + public static List ConvertToModel(DataTable dt) + { + List ts = new List(); + + Type type = typeof(T); + string tempName = ""; + + foreach (DataRow dr in dt.Rows) + { + T t = new T(); + string colvalue = ""; + try + { + PropertyInfo[] propertys = t.GetType().GetProperties(); + foreach (PropertyInfo pi in propertys) + { + tempName = pi.Name; + if (dt.Columns.Contains(tempName)) + { + if (!pi.CanWrite) + { + continue; + } + string TypeName = pi.PropertyType.FullName; + string value = dr[tempName] == DBNull.Value ? "" : Convert.ToString(dr[tempName]); + colvalue = value; + if (pi.PropertyType.Name.ToLower().Contains("datetime")) + { + pi.SetValue(t, string.IsNullOrEmpty(value) ? Convert.ToDateTime("1900-01-01") : Convert.ChangeType(value, pi.PropertyType), null); + } + else if (pi.PropertyType.Name.ToLower().Contains("double")) + { + if (string.IsNullOrEmpty(value)) + { + pi.SetValue(t, 0M); + } + else + { + pi.SetValue(t, string.IsNullOrEmpty(value) ? Convert.ToDouble(0) : Convert.ChangeType(value, pi.PropertyType), null); + } + } + else if (pi.PropertyType.Name.ToLower().Contains("decimal")) + { + if (string.IsNullOrEmpty(value)) + { + pi.SetValue(t, 0M); + } + else + { + pi.SetValue(t, string.IsNullOrEmpty(value) ? Convert.ToDecimal(0) : Convert.ChangeType(value, pi.PropertyType), null); + } + } + else if (pi.PropertyType.Name.ToLower().Contains("int")) + { + pi.SetValue(t, string.IsNullOrEmpty(value) ? 0 : Convert.ChangeType(value, pi.PropertyType), null); + } + else if (pi.PropertyType.Name.ToLower().Contains("bool")) + { + pi.SetValue(t, string.IsNullOrEmpty(value) ? false : Convert.ChangeType(value, pi.PropertyType), null); + } + else if (pi.PropertyType.Name.ToLower().Contains("string")) + { + pi.SetValue(t, string.IsNullOrEmpty(value) ? "" : Convert.ChangeType(value, pi.PropertyType), null); + } + else if (!pi.PropertyType.IsGenericType) + { + pi.SetValue(t, string.IsNullOrEmpty(value) ? null : Convert.ChangeType(value, pi.PropertyType), null); + } + else + { + Type genericTypeDefinition = pi.PropertyType.GetGenericTypeDefinition(); + if (genericTypeDefinition == typeof(Nullable<>)) + { + pi.SetValue(t, string.IsNullOrEmpty(value) ? null : Convert.ChangeType(value, Nullable.GetUnderlyingType(pi.PropertyType)), null); + } + } + } + } + ts.Add(t); + } + catch (Exception ) { } + } + return ts; + } + + } +} diff --git a/backend/ModernWMS.Core/Utility/UtilConvert.cs b/backend/ModernWMS.Core/Utility/UtilConvert.cs new file mode 100644 index 0000000..1093aaa --- /dev/null +++ b/backend/ModernWMS.Core/Utility/UtilConvert.cs @@ -0,0 +1,285 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Text; + +namespace ModernWMS.Core.Utility +{ + /// + /// convert utility + /// + public static class UtilConvert + { + #region object convert function + /// + /// object convert to int + /// + /// value + /// + public static int ObjToInt(this object thisValue) + { + int reval = 0; + if (thisValue == null) + { + return 0; + } + if (string.IsNullOrEmpty(thisValue.ToString())) + { + return 0; + } + if (thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return reval; + } + /// + /// object convert to int + /// + /// value + /// value when error occured + /// + public static int ObjToInt(this object thisValue, int errorValue) + { + + if (thisValue == null) + { + return errorValue; + } + if (string.IsNullOrEmpty(thisValue.ToString())) + { + return 0; + } + if (thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out int reval)) + { + return reval; + } + return errorValue; + } + /// + /// object convert to double + /// + /// value + /// + public static double ObjToDouble(this object thisValue) + { + if (string.IsNullOrEmpty(thisValue.ToString())) + { + return 0; + } + if (thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out double reval)) + { + return reval; + } + return 0; + } + /// + /// object convert to double + /// + /// value + /// value when error occured + /// + public static double ObjToDouble(this object thisValue, double errorValue) + { + if (string.IsNullOrEmpty(thisValue.ToString())) + { + return 0; + } + if (thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out double reval)) + { + return reval; + } + return errorValue; + } + /// + /// object convert to string + /// + /// value + /// + public static string ObjToString(this object thisValue) + { + if (thisValue != null) return thisValue.ToString().Trim(); + return ""; + } + /// + /// object convert to string + /// + /// value + /// value when error occured + /// + public static string ObjToString(this object thisValue, string errorValue) + { + if (thisValue != null) return thisValue.ToString().Trim(); + return errorValue; + } + /// + /// object convert to decimal + /// + /// value + /// + public static decimal ObjToDecimal(this object thisValue) + { + if (string.IsNullOrEmpty(thisValue.ToString())) + { + return 0; + } + if (thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out decimal reval)) + { + return reval; + } + return 0; + } + /// + /// object convert to decimal + /// + /// value + /// value when error occured + /// + public static decimal ObjToDecimal(this object thisValue, decimal errorValue) + { + if (string.IsNullOrEmpty(thisValue.ToString())) + { + return 0; + } + if (thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out decimal reval)) + { + return reval; + } + return errorValue; + } + /// + /// object convert to date + /// + /// value + /// + public static DateTime ObjToDate(this object thisValue) + { + DateTime reval = Convert.ToDateTime("1900-01-01"); + if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) + { + reval = Convert.ToDateTime(thisValue); + } + return reval; + } + /// + /// object convert to date + /// + /// value + /// value when error occured + /// + public static DateTime ObjToDate(this object thisValue, DateTime errorValue) + { + DateTime reval; + if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return errorValue; + } + + /// + /// object convert to bool + /// + /// value + /// + public static bool ObjToBool(this object thisValue) + { + bool reval = false; + if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval)) + { + return reval; + } + return reval; + } + #endregion + + #region compare function + /// + /// less than + /// + /// thisValue + /// compareValue + /// + public static bool IsLessThan(this object thisValue,double compareValue) + { + return Convert.ToDouble(thisValue) < compareValue; + } + /// + /// less than or equal + /// + /// thisValue + /// compareValue + /// + public static bool IsLessThanOrEqual(this object thisValue, double compareValue) + { + return Convert.ToDouble(thisValue) <= compareValue; + } + /// + /// greater than + /// + /// 当前值 + /// 比较值 + /// + public static bool IsGreaterThan(this object thisValue, double compareValue) + { + return Convert.ToDouble(thisValue) > compareValue; + } + /// + /// greater than or equal + /// + /// thisValue + /// compareValue + /// + public static bool IsGreaterThanOrEqual(this object thisValue, double compareValue) + { + return Convert.ToDouble(thisValue) >= compareValue; + } + /// + /// less then + /// + /// thisValue + /// compareValue + /// + public static bool IsLessThan(this object thisValue, DateTime compareValue) + { + return Convert.ToDateTime(thisValue) < compareValue; + } + /// + /// less than or equal + /// + /// thisValue + /// compareValue + /// + public static bool IsLessThanOrEqual(this object thisValue, DateTime compareValue) + { + return Convert.ToDateTime(thisValue) <= compareValue; + } + /// + /// less then + /// + /// thisValue + /// compareValue + /// + public static bool IsGreaterThan(this object thisValue, DateTime compareValue) + { + return Convert.ToDateTime(thisValue) > compareValue; + } + /// + /// ess than or equal + /// + /// thisValue + /// compareValue + /// + public static bool IsGreaterThanOrEqual(this object thisValue, DateTime compareValue) + { + return Convert.ToDateTime(thisValue) >= compareValue; + } + #endregion + + /// + /// default min date + /// + public static DateTime MinDate => Convert.ToDateTime("1900-01-01"); + } +} diff --git a/backend/ModernWMS.WMS/Controllers/Asn/AsnController.cs b/backend/ModernWMS.WMS/Controllers/Asn/AsnController.cs new file mode 100644 index 0000000..8e67187 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Asn/AsnController.cs @@ -0,0 +1,326 @@ +/* + * date:2022-12-22 + * developer:AMo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; +using ModernWMS.Core.JWT; + +namespace ModernWMS.WMS.Controllers +{ + /// + /// asn controller + /// + [Route("asn")] + [ApiController] + [ApiExplorerSettings(GroupName = "WMS")] + public class AsnController : BaseController + { + #region Args + + /// + /// asn Service + /// + private readonly IAsnService _asnService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// asn Service + /// Localizer + public AsnController( + IAsnService asnService + , IStringLocalizer stringLocalizer + ) + { + this._asnService = asnService; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search, sqlTitle input asn_status:0 ~ 4 + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _asnService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _asnService.GetAsync(id); + if (data != null && data.id > 0) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(AsnViewModel viewModel) + { + var (id, msg) = await _asnService.AddAsync(viewModel, CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(AsnViewModel viewModel) + { + var (flag, msg) = await _asnService.UpdateAsync(viewModel); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _asnService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// Bulk modify Goodsowner + /// + /// args + /// + [HttpPut("bulk-modify-goods-owner")] + public async Task> BulkModifyGoodsownerAsync(AsnBulkModifyGoodsOwnerViewModel viewModel) + { + var (flag, msg) = await _asnService.BulkModifyGoodsownerAsync(viewModel); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + #endregion + + #region Flow Api + /// + /// Confirm Delivery + /// change the asn_status from 0 to 1 + /// + /// id + /// + [HttpPut("confirm/{id}")] + public async Task> ConfirmAsync(int id) + { + var (flag, msg) = await _asnService.ConfirmAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// Cancel confirm, change asn_status 1 to 0 + /// + /// id + /// + [HttpPut("confirm-cancel/{id}")] + public async Task> ConfirmCancelAsync(int id) + { + var (flag, msg) = await _asnService.ConfirmCancelAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// Unload + /// change the asn_status from 1 to 2 + /// + /// id + /// + [HttpPut("unload/{id}")] + public async Task> UnloadAsync(int id) + { + var (flag, msg) = await _asnService.UnloadAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// Cancel unload + /// change the asn_status from 2 to 1 + /// + /// id + /// + [HttpPut("unload-cancel/{id}")] + public async Task> UnloadCancelAsync(int id) + { + var (flag, msg) = await _asnService.UnloadCancelAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// sorting, add a new asnsort record and update asn sorted_qty + /// + /// args + /// + [HttpPut("sorting")] + public async Task> SortingAsync(AsnsortInputViewModel viewModel) + { + var (flag, msg) = await _asnService.SortingAsync(viewModel, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// Sorted + /// change the asn_status from 2 to 3 + /// + /// id + /// + [HttpPut("sorted/{id}")] + public async Task> SortedAsync(int id) + { + var (flag, msg) = await _asnService.SortedAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// Cancel sorted + /// change the asn_status from 3 to 2 + /// + /// id + /// + [HttpPut("sorted-cancel/{id}")] + public async Task> SortedCancelAsync(int id) + { + var (flag, msg) = await _asnService.SortedCancelAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// PutAway + /// + /// args + /// + [HttpPut("putaway")] + public async Task> PutAwayAsync(AsnPutAwayInputViewModel viewModel) + { + var (flag, msg) = await _asnService.PutAwayAsync(viewModel, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/Controllers/Customer/CustomerController.cs b/backend/ModernWMS.WMS/Controllers/Customer/CustomerController.cs new file mode 100644 index 0000000..62b3a38 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Customer/CustomerController.cs @@ -0,0 +1,179 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.Controller; +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; + +namespace ModernWMS.WMS.Controllers +{ + /// + /// customer controller + /// + [Route("customer")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class CustomerController : BaseController + { + #region Args + + /// + /// customer Service + /// + private readonly ICustomerService _customerService; + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + + #endregion + + #region constructor + /// + /// constructor + /// + /// customer Service + /// Localizer + public CustomerController( + ICustomerService customerService + , IStringLocalizer stringLocalizer + ) + { + this._customerService = customerService; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _customerService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + /// + /// Get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _customerService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _customerService.GetAsync(id); + if (data != null && data.id > 0) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(CustomerViewModel viewModel) + { + var (id, msg) = await _customerService.AddAsync(viewModel, CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(CustomerViewModel viewModel) + { + var (flag, msg) = await _customerService.UpdateAsync(viewModel); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _customerService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + #region Import + /// + /// import customers by excel + /// + /// excel data + /// + [HttpPost("excel")] + public async Task>> ExcelAsync(List input) + { + var (flag, errorData) = await _customerService.ExcelAsync(input, CurrentUser); + if (flag) + { + return ResultModel>.Success(errorData); + } + else + { + return ResultModel>.Error("", 400, errorData); + } + } + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Controllers/Dispatchlist/DispatchlistController.cs b/backend/ModernWMS.WMS/Controllers/Dispatchlist/DispatchlistController.cs new file mode 100644 index 0000000..ddf9ab1 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Dispatchlist/DispatchlistController.cs @@ -0,0 +1,343 @@ +/* + * date:2022-12-27 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; +namespace ModernWMS.WMS.Controllers +{ + /// + /// dispatchlist controller + /// + [Route("dispatchlist")] + [ApiController] + [ApiExplorerSettings(GroupName = "WMS")] + public class DispatchlistController : BaseController + { + #region Args + + /// + /// dispatchlist Service + /// + private readonly IDispatchlistService _dispatchlistService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// dispatchlist Service + /// Localizer + public DispatchlistController( + IDispatchlistService dispatchlistService + , IStringLocalizer stringLocalizer + ) + { + this._dispatchlistService = dispatchlistService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _dispatchlistService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + /// + /// advanced dispatch order page search + /// + /// args + /// + [HttpPost("advanced-list")] + public async Task>> AdvancedDispatchlistPageAsync(PageSearch pageSearch) + { + var (data, totals) = await _dispatchlistService.AdvancedDispatchlistPageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(List viewModel) + { + var (flag, msg) = await _dispatchlistService.AddAsync(viewModel,CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + /// + /// update dispatchlist with same dispatch_no + /// + /// viewModel + /// + [HttpPut] + public async Task> UpdateAsycn(List viewModel) + { + var (flag, msg) = await _dispatchlistService.UpdateAsycn(viewModel, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + /// + /// get dispatchlist by dispatch_no + /// + /// dispatch_no + /// + [HttpGet("by-dispatch_no")] + public async Task>> GetByDispatchlistNo(string dispatch_no) + { + var datas = await _dispatchlistService.GetByDispatchlistNo(dispatch_no, CurrentUser); + return ResultModel>.Success(datas); + } + /// + /// get Dispatchlist details with available stock + /// + /// dispatch_no + /// + [HttpGet("confirm-check")] + public async Task>> ConfirmOrderCheck(string dispatch_no) + { + var datas = await _dispatchlistService.ConfirmOrderCheck(dispatch_no, CurrentUser); + return ResultModel>.Success(datas); + } + + /// + /// get pick list by dispatch_id + /// + /// dispatch_id + /// + [HttpGet("pick-list")] + public async Task>> GetPickListByDispatchID(int dispatch_id) + { + var datas = await _dispatchlistService.GetPickListByDispatchID(dispatch_id); + return ResultModel>.Success(datas); + } + /// + /// delete a record + /// + /// dispatch_no + /// + [HttpDelete] + public async Task> DeleteAsync(string dispatch_no) + { + var (flag, msg) = await _dispatchlistService.DeleteAsync(dispatch_no,CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + /// + /// Confirm orders and create dispatchpicklist + /// + /// viewModels + /// + [HttpPost("confirm-order")] + public async Task> ConfirmOrder(List viewModels) + { + var (flag, msg) = await _dispatchlistService.ConfirmOrder(viewModels, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + /// + /// confirm dispatchpicklist picked by dispatch_no + /// + /// viewModels + /// + [HttpPut("confirm-pick-dispatchlistno")] + public async Task> ConfirmPickByDispatchNo(string dispatch_no) + { + var (flag, msg) = await _dispatchlistService.ConfirmPickByDispatchNo(dispatch_no, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// package dispatchpicklist + /// + /// viewModels + /// + [HttpPost("package")] + public async Task> Package(List viewModels) + { + var (flag, msg) = await _dispatchlistService.Package(viewModels, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// weight dispatchpicklist + /// + /// viewModels + /// + [HttpPost("weight")] + public async Task> Weight(List viewModels) + { + var (flag, msg) = await _dispatchlistService.Weight(viewModels, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// dispatchpicklist outbound delivery + /// + /// viewModels + /// + [HttpPost("delivery")] + public async Task> Delivery(List viewModels) + { + var (flag, msg) = await _dispatchlistService.Delivery(viewModels, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// set dispatchlist freightfee + /// + /// viewModels + /// + [HttpPost("freightfee")] + public async Task> SetFreightfee(List viewModels) + { + var (flag, msg) = await _dispatchlistService.SetFreightfee(viewModels); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// sign for arrival + /// + /// viewModels + /// + [HttpPost("sign")] + public async Task> SignForArrival(List viewModels) + { + var (flag, msg) = await _dispatchlistService.SignForArrival(viewModels); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + /// + /// cancel order opration + /// + /// viewModel + /// + [HttpPost("cancel-order")] + public async Task> CancelOrderOpration(CancelOrderOprationViewModel viewModel) + { + var (flag, msg) = await _dispatchlistService.CancelOrderOpration(viewModel,CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + /// + /// cancel dispatchlist detail opration + /// + /// id + /// + [HttpPut("cancel-order")] + public async Task> CancelDispatchlistDetailOpration(int id) + { + var (flag, msg) = await _dispatchlistService.CancelDispatchlistDetailOpration(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/Freightfee/FreightfeeController.cs b/backend/ModernWMS.WMS/Controllers/Freightfee/FreightfeeController.cs new file mode 100644 index 0000000..058fe86 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Freightfee/FreightfeeController.cs @@ -0,0 +1,182 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; +namespace ModernWMS.WMS.Controllers +{ + /// + /// freightfee controller + /// + [Route("freightfee")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class FreightfeeController : BaseController + { + #region Args + + /// + /// freightfee Service + /// + private readonly IFreightfeeService _freightfeeService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// freightfee Service + /// Localizer + public FreightfeeController( + IFreightfeeService freightfeeService + , IStringLocalizer stringLocalizer + ) + { + this._freightfeeService = freightfeeService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _freightfeeService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _freightfeeService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _freightfeeService.GetAsync(id); + if (data!=null) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(FreightfeeViewModel viewModel) + { + var (id, msg) = await _freightfeeService.AddAsync(viewModel,CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(FreightfeeViewModel viewModel) + { + var (flag, msg) = await _freightfeeService.UpdateAsync(viewModel); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _freightfeeService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// import freight fee by excel + /// + /// excel datas + /// + [HttpPost("excel")] + public async Task> ExcelAsync(List excel_datas) + { + var (flag, msg) = await _freightfeeService.ExcelAsync(excel_datas, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/GoodsOwner/GoodsownerController.cs b/backend/ModernWMS.WMS/Controllers/GoodsOwner/GoodsownerController.cs new file mode 100644 index 0000000..af4df5b --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/GoodsOwner/GoodsownerController.cs @@ -0,0 +1,179 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.Controller; +using ModernWMS.Core.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using ModernWMS.WMS.Services; + +namespace ModernWMS.WMS.Controllers +{ + /// + /// goodsowner controller + /// + [Route("goodsowner")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class GoodsownerController : BaseController + { + #region Args + + /// + /// goodsowner Service + /// + private readonly IGoodsownerService _goodsownerService; + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + + #endregion + + #region constructor + /// + /// constructor + /// + /// goodsowner Service + /// Localizer + public GoodsownerController( + IGoodsownerService goodsownerService + , IStringLocalizer stringLocalizer + ) + { + this._goodsownerService = goodsownerService; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _goodsownerService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + /// + /// Get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _goodsownerService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _goodsownerService.GetAsync(id); + if (data != null && data.id > 0) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(GoodsownerViewModel viewModel) + { + var (id, msg) = await _goodsownerService.AddAsync(viewModel, CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(GoodsownerViewModel viewModel) + { + var (flag, msg) = await _goodsownerService.UpdateAsync(viewModel); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _goodsownerService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + #region Import + /// + /// import goodsowners by excel + /// + /// excel data + /// + [HttpPost("excel")] + public async Task>> ExcelAsync(List input) + { + var (flag, errorData) = await _goodsownerService.ExcelAsync(input, CurrentUser); + if (flag) + { + return ResultModel>.Success(errorData); + } + else + { + return ResultModel>.Error("", 400, errorData); + } + } + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Controllers/Goodslocation/GoodslocationController.cs b/backend/ModernWMS.WMS/Controllers/Goodslocation/GoodslocationController.cs new file mode 100644 index 0000000..998d90d --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Goodslocation/GoodslocationController.cs @@ -0,0 +1,174 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; +namespace ModernWMS.WMS.Controllers +{ + /// + /// goodslocation controller + /// + [Route("goodslocation")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class GoodslocationController : BaseController + { + #region Args + + /// + /// goodslocation Service + /// + private readonly IGoodslocationService _goodslocationService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// goodslocation Service + /// Localizer + public GoodslocationController( + IGoodslocationService goodslocationService + , IStringLocalizer stringLocalizer + ) + { + this._goodslocationService = goodslocationService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// get select items + /// + /// + [HttpGet("location-by-warehouseare_id")] + public async Task>> GetSelectItemsAsnyc(int warehousearea_id) + { + var datas = await _goodslocationService.GetGoodslocationByWarehouse_area_id(warehousearea_id, CurrentUser); + return ResultModel>.Success(datas); + } + + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _goodslocationService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _goodslocationService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _goodslocationService.GetAsync(id); + if (data!=null) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(GoodslocationViewModel viewModel) + { + var (id, msg) = await _goodslocationService.AddAsync(viewModel,CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(GoodslocationViewModel viewModel) + { + var (flag, msg) = await _goodslocationService.UpdateAsync(viewModel, CurrentUser); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _goodslocationService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/Rolemenu/RolemenuController.cs b/backend/ModernWMS.WMS/Controllers/Rolemenu/RolemenuController.cs new file mode 100644 index 0000000..afc5baf --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Rolemenu/RolemenuController.cs @@ -0,0 +1,181 @@ +/* + * date:2022-12-20 + * developer:AMo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; + + namespace ModernWMS.WMS.Controllers + { + /// + /// rolemenu controller + /// + [Route("rolemenu")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class RolemenuController : BaseController + { + #region Args + + /// + /// rolemenu Service + /// + private readonly IRolemenuService _rolemenuService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// rolemenu Service + /// Localizer + public RolemenuController( + IRolemenuService rolemenuService + , IStringLocalizer stringLocalizer + ) + { + this._rolemenuService = rolemenuService; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// Get menu's authority by user role id + /// + /// user role id + /// + [HttpGet("authority")] + public async Task>> GetMenusByRoleId(int userrole_id) + { + var data = await _rolemenuService.GetMenusByRoleId(userrole_id); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + /// + /// get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _rolemenuService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + /// + /// Get all menus + /// + /// + [HttpGet("menus")] + public async Task>> GetAllMenusAsync() + { + var data = await _rolemenuService.GetAllMenusAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int userrole_id) + { + var data = await _rolemenuService.GetAsync(userrole_id); + if (data != null && data.userrole_id > 0) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(RolemenuBothViewModel viewModel) + { + var (id, msg) = await _rolemenuService.AddAsync(viewModel, CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(RolemenuBothViewModel viewModel) + { + var (flag, msg) = await _rolemenuService.UpdateAsync(viewModel, CurrentUser); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// userrole id + /// + [HttpDelete] + public async Task> DeleteAsync(int userrole_id) + { + var (flag, msg) = await _rolemenuService.DeleteAsync(userrole_id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/Sku/CategoryController.cs b/backend/ModernWMS.WMS/Controllers/Sku/CategoryController.cs new file mode 100644 index 0000000..0d3199a --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Sku/CategoryController.cs @@ -0,0 +1,147 @@ +/* + * date:2022-12-20 + * developer:AMo + */ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.Controller; +using ModernWMS.Core.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; + +namespace ModernWMS.WMS.Controllers +{ + /// + /// category controller + /// + [Route("category")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class CategoryController : BaseController + { + #region Args + + /// + /// category Service + /// + private readonly ICategoryService _categoryService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// category Service + /// Localizer + public CategoryController( + ICategoryService categoryService + , IStringLocalizer stringLocalizer + ) + { + this._categoryService = categoryService; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _categoryService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _categoryService.GetAsync(id); + if (data != null) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(CategoryViewModel viewModel) + { + var (id, msg) = await _categoryService.AddAsync(viewModel, CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(CategoryViewModel viewModel) + { + var (flag, msg) = await _categoryService.UpdateAsync(viewModel); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _categoryService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } +} + diff --git a/backend/ModernWMS.WMS/Controllers/Sku/SpuController.cs b/backend/ModernWMS.WMS/Controllers/Sku/SpuController.cs new file mode 100644 index 0000000..c94678f --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Sku/SpuController.cs @@ -0,0 +1,164 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; + +namespace ModernWMS.WMS.Controllers +{ + /// + /// spu controller + /// + [Route("spu")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class SpuController : BaseController + { + #region Args + + /// + /// spu Service + /// + private readonly ISpuService _spuService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// spu Service + /// Localizer + public SpuController( + ISpuService spuService + , IStringLocalizer stringLocalizer + ) + { + this._spuService = spuService; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _spuService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _spuService.GetAsync(id); + if (data != null && data.id > 0) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + + /// + /// get sku info by sku_id + /// + /// sku_id + /// + [HttpGet("sku")] + public async Task> GetSkuAsync(int sku_id) + { + var data = await _spuService.GetSkuAsync(sku_id); + if (data != null && data.sku_id > 0) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(SpuBothViewModel viewModel) + { + var (id, msg) = await _spuService.AddAsync(viewModel, CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(SpuBothViewModel viewModel) + { + var (flag, msg) = await _spuService.UpdateAsync(viewModel); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _spuService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } +} + diff --git a/backend/ModernWMS.WMS/Controllers/Stock/StockController.cs b/backend/ModernWMS.WMS/Controllers/Stock/StockController.cs new file mode 100644 index 0000000..4ecf4f8 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Stock/StockController.cs @@ -0,0 +1,122 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; + + namespace ModernWMS.WMS.Controllers + { + /// + /// stock controller + /// + [Route("stock")] + [ApiController] + [ApiExplorerSettings(GroupName = "WMS")] + public class StockController : BaseController + { + #region Args + + /// + /// stock Service + /// + private readonly IStockService _stockService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// stock Service + /// Localizer + public StockController( + IStockService stockService + , IStringLocalizer stringLocalizer + ) + { + this._stockService = stockService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// stock details page search + /// + /// args + /// + [HttpPost("stock-list")] + public async Task>> StockPageAsync(PageSearch pageSearch) + { + var (data, totals) = await _stockService.StockPageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + /// + /// location stock page search + /// + /// args + /// + [HttpPost("location-list")] + public async Task>> LocationStockPageAsync(PageSearch pageSearch) + { + var (data, totals) = await _stockService.LocationStockPageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// page search select + /// + /// args + /// + [HttpPost("select")] + public async Task>> SelectPageAsync(PageSearch pageSearch) + { + var (data, totals) = await _stockService.SelectPageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// sku page search select + /// + /// args + /// + [HttpPost("sku-select")] + public async Task>> SkuSelectPageAsync(PageSearch pageSearch) + { + var (data, totals) = await _stockService.SkuSelectPageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/Stockadjust/StockadjustController.cs b/backend/ModernWMS.WMS/Controllers/Stockadjust/StockadjustController.cs new file mode 100644 index 0000000..9439c6c --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Stockadjust/StockadjustController.cs @@ -0,0 +1,72 @@ +/* + * date:2022-12-26 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; +namespace ModernWMS.WMS.Controllers +{ + /// + /// stockadjust controller + /// + [Route("stockadjust")] + [ApiController] + [ApiExplorerSettings(GroupName = "WMS")] + public class StockadjustController : BaseController + { + #region Args + + /// + /// stockadjust Service + /// + private readonly IStockadjustService _stockadjustService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// stockadjust Service + /// Localizer + public StockadjustController( + IStockadjustService stockadjustService + , IStringLocalizer stringLocalizer + ) + { + this._stockadjustService = stockadjustService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _stockadjustService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/Stockfreeze/StockfreezeController.cs b/backend/ModernWMS.WMS/Controllers/Stockfreeze/StockfreezeController.cs new file mode 100644 index 0000000..e68be05 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Stockfreeze/StockfreezeController.cs @@ -0,0 +1,164 @@ +/* + * date:2022-12-26 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; + + namespace ModernWMS.WMS.Controllers + { + /// + /// stockfreeze controller + /// + [Route("stockfreeze")] + [ApiController] + [ApiExplorerSettings(GroupName = "WMS")] + public class StockfreezeController : BaseController + { + #region Args + + /// + /// stockfreeze Service + /// + private readonly IStockfreezeService _stockfreezeService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// stockfreeze Service + /// Localizer + public StockfreezeController( + IStockfreezeService stockfreezeService + , IStringLocalizer stringLocalizer + ) + { + this._stockfreezeService = stockfreezeService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _stockfreezeService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _stockfreezeService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _stockfreezeService.GetAsync(id); + if (data!=null) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(StockfreezeViewModel viewModel) + { + var (id, msg) = await _stockfreezeService.AddAsync(viewModel,CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(StockfreezeViewModel viewModel) + { + var (flag, msg) = await _stockfreezeService.UpdateAsync(viewModel); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _stockfreezeService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/Stockmove/StockmoveController.cs b/backend/ModernWMS.WMS/Controllers/Stockmove/StockmoveController.cs new file mode 100644 index 0000000..3c91263 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Stockmove/StockmoveController.cs @@ -0,0 +1,164 @@ +/* + * date:2022-12-27 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; + + namespace ModernWMS.WMS.Controllers + { + /// + /// stockmove controller + /// + [Route("stockmove")] + [ApiController] + [ApiExplorerSettings(GroupName = "WMS")] + public class StockmoveController : BaseController + { + #region Args + + /// + /// stockmove Service + /// + private readonly IStockmoveService _stockmoveService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// stockmove Service + /// Localizer + public StockmoveController( + IStockmoveService stockmoveService + , IStringLocalizer stringLocalizer + ) + { + this._stockmoveService = stockmoveService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _stockmoveService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _stockmoveService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _stockmoveService.GetAsync(id); + if (data!=null) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(StockmoveViewModel viewModel) + { + var (id, msg) = await _stockmoveService.AddAsync(viewModel,CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// confirm move + /// + /// id + /// + [HttpPut] + public async Task> Confirm(int id) + { + var (flag, msg) = await _stockmoveService.Confirm(id,CurrentUser); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _stockmoveService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/Stockprocess/StockprocessController.cs b/backend/ModernWMS.WMS/Controllers/Stockprocess/StockprocessController.cs new file mode 100644 index 0000000..818431b --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Stockprocess/StockprocessController.cs @@ -0,0 +1,201 @@ +/* + * date:2022-12-23 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; + + namespace ModernWMS.WMS.Controllers + { + /// + /// stockprocess controller + /// + [Route("stockprocess")] + [ApiController] + [ApiExplorerSettings(GroupName = "WMS")] + public class StockprocessController : BaseController + { + #region Args + + /// + /// stockprocess Service + /// + private readonly IStockprocessService _stockprocessService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// stockprocess Service + /// Localizer + public StockprocessController( + IStockprocessService stockprocessService + , IStringLocalizer stringLocalizer + ) + { + this._stockprocessService = stockprocessService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _stockprocessService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _stockprocessService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _stockprocessService.GetAsync(id); + if (data!=null) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(StockprocessViewModel viewModel) + { + var (id, msg) = await _stockprocessService.AddAsync(viewModel,CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(StockprocessViewModel viewModel) + { + var (flag, msg) = await _stockprocessService.UpdateAsync(viewModel); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _stockprocessService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + /// + /// confirm processing + /// + /// + /// + [HttpPut("process-confirm")] + public async Task> ConfirmProcess(int id) + { + var (flag, msg) = await _stockprocessService.ConfirmProcess(id,CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// confirm adjustment + /// + /// + /// + [HttpPut("adjustment-confirm")] + public async Task> ConfirmAdjustment(int id) + { + var (flag, msg) = await _stockprocessService.ConfirmAdjustment(id, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/Stocktaking/StocktakingController.cs b/backend/ModernWMS.WMS/Controllers/Stocktaking/StocktakingController.cs new file mode 100644 index 0000000..6700ecf --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Stocktaking/StocktakingController.cs @@ -0,0 +1,165 @@ +/* + * date:2022-12-30 + * developer:AMo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; + + namespace ModernWMS.WMS.Controllers + { + /// + /// stocktaking controller + /// + [Route("stocktaking")] + [ApiController] + [ApiExplorerSettings(GroupName = "WMS")] + public class StocktakingController : BaseController + { + #region Args + + /// + /// stocktaking Service + /// + private readonly IStocktakingService _stocktakingService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// stocktaking Service + /// Localizer + public StocktakingController( + IStocktakingService stocktakingService + , IStringLocalizer stringLocalizer + ) + { + this._stocktakingService = stocktakingService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _stocktakingService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _stocktakingService.GetAsync(id); + if (data!=null) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(StocktakingBasicViewModel viewModel) + { + var (id, msg) = await _stocktakingService.AddAsync(viewModel,CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// Confirm a record + /// + /// args + /// + [HttpPut] + public async Task> PutAsync(StocktakingConfirmViewModel viewModel) + { + var (flag, msg) = await _stocktakingService.PutAsync(viewModel, CurrentUser); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// confrim a record and change stock and add to stockadjust + /// + /// id + /// + [HttpPut("adjustment-confirm")] + public async Task> ConfirmAsync(int id) + { + var (flag, msg) = await _stocktakingService.ConfirmAsync(id, CurrentUser); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _stocktakingService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/Warehouse/WarehouseController.cs b/backend/ModernWMS.WMS/Controllers/Warehouse/WarehouseController.cs new file mode 100644 index 0000000..181d800 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Warehouse/WarehouseController.cs @@ -0,0 +1,195 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; +using ModernWMS.WMS.Services; + +namespace ModernWMS.WMS.Controllers +{ + /// + /// warehouse controller + /// + [Route("warehouse")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class WarehouseController : BaseController + { + #region Args + + /// + /// warehouse Service + /// + private readonly IWarehouseService _warehouseService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// warehouse Service + /// Localizer + public WarehouseController( + IWarehouseService warehouseService + , IStringLocalizer stringLocalizer + ) + { + this._warehouseService = warehouseService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// get select items + /// + /// + [HttpGet("select-item")] + public async Task>> GetSelectItemsAsnyc() + { + var datas = await _warehouseService.GetSelectItemsAsnyc(CurrentUser); + return ResultModel>.Success(datas); + } + + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _warehouseService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _warehouseService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _warehouseService.GetAsync(id); + if (data!=null) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(WarehouseViewModel viewModel) + { + var (id, msg) = await _warehouseService.AddAsync(viewModel,CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(WarehouseViewModel viewModel) + { + var (flag, msg) = await _warehouseService.UpdateAsync(viewModel,CurrentUser); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _warehouseService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// import warehouses by excel + /// + /// excel datas + /// + [HttpPost("excel")] + public async Task> ExcelAsync(List excel_datas) + { + var (flag, msg) = await _warehouseService.ExcelAsync(excel_datas, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/Warehousearea/WarehouseareaController.cs b/backend/ModernWMS.WMS/Controllers/Warehousearea/WarehouseareaController.cs new file mode 100644 index 0000000..843f058 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/Warehousearea/WarehouseareaController.cs @@ -0,0 +1,174 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; +namespace ModernWMS.WMS.Controllers +{ + /// + /// warehousearea controller + /// + [Route("warehousearea")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class WarehouseareaController : BaseController + { + #region Args + + /// + /// warehousearea Service + /// + private readonly IWarehouseareaService _warehouseareaService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// warehousearea Service + /// Localizer + public WarehouseareaController( + IWarehouseareaService warehouseareaService + , IStringLocalizer stringLocalizer + ) + { + this._warehouseareaService = warehouseareaService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// get warehousearea select items by warehouse_id + /// + /// + [HttpGet("areas-by-warehouse_id")] + public async Task>> GetSelectItemsAsnyc(int warehouse_id) + { + var datas = await _warehouseareaService.GetWarehouseareaByWarehouse_id(warehouse_id,CurrentUser); + return ResultModel>.Success(datas); + } + + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _warehouseareaService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync(int warehouse_id) + { + var data = await _warehouseareaService.GetAllAsync( warehouse_id, CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _warehouseareaService.GetAsync(id); + if (data!=null) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(WarehouseareaViewModel viewModel) + { + var (id, msg) = await _warehouseareaService.AddAsync(viewModel,CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(WarehouseareaViewModel viewModel) + { + var (flag, msg) = await _warehouseareaService.UpdateAsync(viewModel,CurrentUser); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _warehouseareaService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/company/CompanyController.cs b/backend/ModernWMS.WMS/Controllers/company/CompanyController.cs new file mode 100644 index 0000000..cddab20 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/company/CompanyController.cs @@ -0,0 +1,142 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.Controller; +using ModernWMS.Core.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; + +namespace ModernWMS.WMS.Controllers +{ + /// + /// company controller + /// + [Route("company")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class CompanyController: BaseController + { + #region Args + + /// + /// company Service + /// + private readonly ICompanyService _companyService; + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + + #endregion + + #region constructor + /// + /// constructor + /// + /// company Service + /// Localizer + public CompanyController( + ICompanyService companyService + , IStringLocalizer stringLocalizer + ) + { + this._companyService = companyService; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// Get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _companyService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _companyService.GetAsync(id); + if (data != null && data.id > 0) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(CompanyViewModel viewModel) + { + var (id, msg) = await _companyService.AddAsync(viewModel, CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(CompanyViewModel viewModel) + { + var (flag, msg) = await _companyService.UpdateAsync(viewModel); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _companyService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Controllers/supplier/SupplierController.cs b/backend/ModernWMS.WMS/Controllers/supplier/SupplierController.cs new file mode 100644 index 0000000..063a1e3 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/supplier/SupplierController.cs @@ -0,0 +1,183 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; + +namespace ModernWMS.WMS.Controllers +{ + /// + /// supplier controller + /// + [Route("supplier")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class SupplierController : BaseController + { + #region Args + + /// + /// supplier Service + /// + private readonly ISupplierService _supplierService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// supplier Service + /// Localizer + public SupplierController( + ISupplierService supplierService + , IStringLocalizer stringLocalizer + ) + { + this._supplierService = supplierService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _supplierService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _supplierService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _supplierService.GetAsync(id); + if (data!=null) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(SupplierViewModel viewModel) + { + var (id, msg) = await _supplierService.AddAsync(viewModel,CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(SupplierViewModel viewModel) + { + var (flag, msg) = await _supplierService.UpdateAsync(viewModel, CurrentUser); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _supplierService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// import suppliers by excel + /// + /// excel datas + /// + [HttpPost("excel")] + public async Task> ExcelAsync(List excel_datas) + { + var (flag, msg) = await _supplierService.ExcelAsync(excel_datas, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Controllers/user/UserController.cs b/backend/ModernWMS.WMS/Controllers/user/UserController.cs new file mode 100644 index 0000000..4cd02e9 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/user/UserController.cs @@ -0,0 +1,248 @@ +/* + * date:2022-12-20 + * developer:NoNo + */ +using Microsoft.AspNetCore.Mvc; +using ModernWMS.Core.Controller; +using ModernWMS.Core.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using Microsoft.Extensions.Localization; +using Microsoft.AspNetCore.Authorization; + +namespace ModernWMS.WMS.Controllers +{ + /// + /// user controller + /// + [Route("user")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class UserController : BaseController + { + #region Args + + /// + /// user Service + /// + private readonly IUserService _userService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// user Service + /// Localizer + public UserController( + IUserService userService + , IStringLocalizer stringLocalizer + ) + { + this._userService = userService; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// get select items + /// + /// + [HttpGet("select-item")] + public async Task>> GetSelectItemsAsnyc() + { + var datas = await _userService.GetSelectItemsAsnyc(CurrentUser); + return ResultModel>.Success(datas); + } + /// + /// page search + /// + /// args + /// + [HttpPost("list")] + public async Task>> PageAsync(PageSearch pageSearch) + { + var (data, totals) = await _userService.PageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + + /// + /// Get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _userService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// Get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _userService.GetAsync(id); + if (data != null) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["not_exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(UserViewModel viewModel) + { + viewModel.creator = CurrentUser.user_name; + var (id, msg) = await _userService.AddAsync(viewModel, CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + /// + /// register a new tenant + /// + /// args + /// + [AllowAnonymous] + [HttpPost("register")] + public async Task> Register(RegisterViewModel viewModel) + { + var (flag, msg) = await _userService.Register(viewModel); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + /// + /// import users by excel + /// + /// excel datas + /// + [HttpPost("excel")] + public async Task> ExcelAsync(List excel_datas) + { + var (flag, msg) = await _userService.ExcelAsync(excel_datas, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(UserViewModel viewModel) + { + var (flag, msg) = await _userService.UpdateAsync(viewModel, CurrentUser); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _userService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + /// + /// reset password + /// + /// viewmodel + /// + [HttpPost("reset-pwd")] + public async Task> ResetPwd(BatchOperationViewModel viewModel) + { + var (flag, msg) = await _userService.ResetPwd(viewModel); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + /// + /// change password + /// + /// viewmodel + /// + [HttpPost("change-pwd")] + public async Task> ChangePwd(UserChangePwdViewModel viewModel) + { + var (flag, msg) = await _userService.ChangePwd(viewModel); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } +} + diff --git a/backend/ModernWMS.WMS/Controllers/userrole/UserroleController.cs b/backend/ModernWMS.WMS/Controllers/userrole/UserroleController.cs new file mode 100644 index 0000000..f6efad4 --- /dev/null +++ b/backend/ModernWMS.WMS/Controllers/userrole/UserroleController.cs @@ -0,0 +1,163 @@ +/* + * date:2022-12-20 + * developer:NoNo + */ + using Microsoft.AspNetCore.Mvc; + using ModernWMS.Core.Controller; + using ModernWMS.Core.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; + + namespace ModernWMS.WMS.Controllers + { + /// + /// userrole controller + /// + [Route("userrole")] + [ApiController] + [ApiExplorerSettings(GroupName = "Base")] + public class UserroleController : BaseController + { + #region Args + + /// + /// userrole Service + /// + private readonly IUserroleService _userroleService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// constructor + /// + /// userrole Service + /// Localizer + public UserroleController( + IUserroleService userroleService + , IStringLocalizer stringLocalizer + ) + { + this._userroleService = userroleService; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// save all records + /// + /// viewmodel + /// + [HttpPost("save")] + public async Task> SaveAllAsync(List viewModels) + { + var (flag,msg) = await _userroleService.BulkSaveAsync(viewModels, CurrentUser); + if(flag) + { + return ResultModel.Success(msg); + } + return ResultModel.Error(msg); + } + + /// + /// get all records + /// + /// args + [HttpGet("all")] + public async Task>> GetAllAsync() + { + var data = await _userroleService.GetAllAsync(CurrentUser); + if (data.Any()) + { + return ResultModel>.Success(data); + } + else + { + return ResultModel>.Success(new List()); + } + } + + /// + /// get a record by id + /// + /// args + [HttpGet] + public async Task> GetAsync(int id) + { + var data = await _userroleService.GetAsync(id); + if (data!=null) + { + return ResultModel.Success(data); + } + else + { + return ResultModel.Error(_stringLocalizer["exists_entity"]); + } + } + /// + /// add a new record + /// + /// args + /// + [HttpPost] + public async Task> AddAsync(UserroleViewModel viewModel) + { + var (id, msg) = await _userroleService.AddAsync(viewModel,CurrentUser); + if (id > 0) + { + return ResultModel.Success(id); + } + else + { + return ResultModel.Error(msg); + } + } + + /// + /// update a record + /// + /// args + /// + [HttpPut] + public async Task> UpdateAsync(UserroleViewModel viewModel) + { + var (flag, msg) = await _userroleService.UpdateAsync(viewModel, CurrentUser); + if (flag) + { + return ResultModel.Success(flag); + } + else + { + return ResultModel.Error(msg, 400, flag); + } + } + + /// + /// delete a record + /// + /// id + /// + [HttpDelete] + public async Task> DeleteAsync(int id) + { + var (flag, msg) = await _userroleService.DeleteAsync(id); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } + #endregion + + } + } + diff --git a/backend/ModernWMS.WMS/Entities/Models/Asn/AsnEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Asn/AsnEntity.cs new file mode 100644 index 0000000..9fa1a3a --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Asn/AsnEntity.cs @@ -0,0 +1,132 @@ +/* + * date:2022-12-22 + * developer:AMo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// asn entity + /// + [Table("asn")] + public class AsnEntity : BaseModel + { + + #region Property + + /// + /// asn_no + /// + public string asn_no { get; set; } = string.Empty; + + /// + /// asn_status + /// + public byte asn_status { get; set; } = 0; + + /// + /// spu_id + /// + public int spu_id { get; set; } = 0; + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// asn_qty + /// + public int asn_qty { get; set; } = 0; + + /// + /// actual_qty + /// + public int actual_qty { get; set; } = 0; + + /// + /// sorted_qty + /// + public int sorted_qty { get; set; } = 0; + + /// + /// shortage_qty + /// + public int shortage_qty { get; set; } = 0; + + /// + /// more_qty + /// + public int more_qty { get; set; } = 0; + + /// + /// damage_qty + /// + public int damage_qty { get; set; } = 0; + + /// + /// weight + /// + public decimal weight { get; set; } = 0; + + /// + /// volume + /// + public decimal volume { get; set; } = 0; + + /// + /// supplier_id + /// + public int supplier_id { get; set; } = 0; + + /// + /// supplier_name + /// + public string supplier_name { get; set; } = string.Empty; + + /// + /// goods_owner_id + /// + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_owner_name + /// + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = DateTime.Now; + + /// + /// is_valid + /// + public bool is_valid { get; set; } = true; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 1; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Asn/AsnsortEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Asn/AsnsortEntity.cs new file mode 100644 index 0000000..78aa2e6 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Asn/AsnsortEntity.cs @@ -0,0 +1,59 @@ +/* + * date:2022-12-30 + * developer:AMo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// asnsort entity + /// + [Table("asnsort")] + public class AsnsortEntity : BaseModel + { + #region Property + + /// + /// asn_id + /// + public int asn_id { get; set; } = 0; + + /// + /// sorted_qty + /// + public int sorted_qty { get; set; } = 0; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = DateTime.Now; + + /// + /// is_valid + /// + public bool is_valid { get; set; } = true; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 1; + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Customer/CustomerEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Customer/CustomerEntity.cs new file mode 100644 index 0000000..bc229f3 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Customer/CustomerEntity.cs @@ -0,0 +1,69 @@ +using ModernWMS.Core.Models; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// customer entity + /// + [Table("customer")] + public class CustomerEntity : BaseModel + { + #region Property + /// + /// customer name + /// + public string customer_name { get; set; } = string.Empty; + + /// + /// city + /// + public string city { get; set; } = string.Empty; + + /// + /// address + /// + public string address { get; set; } = string.Empty; + + /// + /// email + /// + public string email { get; set; } = string.Empty; + + /// + /// manager + /// + public string manager { get; set; } = string.Empty; + + /// + /// contact tel + /// + public string contact_tel { get; set; } = string.Empty; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create time + /// + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last update time + /// + public DateTime last_update_time { get; set; } = DateTime.Now; + + /// + /// valid + /// + public bool is_valid { get; set; } = true; + + /// + /// the tenant id + /// + public long tenant_id { get; set; } = 1; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Dispatchlist/DispatchlistEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Dispatchlist/DispatchlistEntity.cs new file mode 100644 index 0000000..4dcb4d8 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Dispatchlist/DispatchlistEntity.cs @@ -0,0 +1,183 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// dispatchlist entity + /// + [Table("dispatchlist")] + public class DispatchlistEntity : BaseModel + { + + #region Property + + /// + /// dispatch_no + /// + public string dispatch_no { get; set; } = string.Empty; + + /// + /// dispatch_status + /// + public byte dispatch_status { get; set; } = 0; + + /// + /// customer_id + /// + public int customer_id { get; set; } = 0; + + /// + /// customer_name + /// + public string customer_name { get; set; } = string.Empty; + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// qty + /// + public int qty { get; set; } = 0; + + /// + /// weight + /// + public decimal weight { get; set; } = 0; + + /// + /// volume + /// + public decimal volume { get; set; } = 0; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// damage_qty + /// + public int damage_qty { get; set; } = 0; + + /// + /// lock_qty + /// + public int lock_qty { get; set; } = 0; + + /// + /// picked_qty + /// + public int picked_qty { get; set; } = 0; + + /// + /// intrasit_qty + /// + public int intrasit_qty { get; set; } = 0; + + /// + /// package_qty + /// + public int package_qty { get; set; } = 0; + + /// + /// weighing_qty + /// + public int weighing_qty { get; set; } = 0; + + /// + /// actual_qty + /// + public int actual_qty { get; set; } = 0; + + /// + /// sign_qty + /// + public int sign_qty { get; set; } = 0; + + /// + /// package_no + /// + public string package_no { get; set; } = string.Empty; + + /// + /// package_person + /// + public string package_person { get; set; } = string.Empty; + + /// + /// package_time + /// + public DateTime package_time { get; set; } = UtilConvert.MinDate; + + /// + /// weighing_no + /// + public string weighing_no { get; set; } = string.Empty; + + /// + /// weighing_person + /// + public string weighing_person { get; set; } = string.Empty; + + /// + /// weighing_weight + /// + public decimal weighing_weight { get; set; } = 0; + + /// + /// waybill_no + /// + public string waybill_no { get; set; } = string.Empty; + + /// + /// carrier + /// + public string carrier { get; set; } = string.Empty; + + /// + /// freightfee + /// + public decimal freightfee { get; set; } = 0; + + /// + /// last_update_time + /// + [ConcurrencyCheck] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + + #endregion + + + #region detail table + + /// + /// detail table + /// + public List detailList { get; set; } = new List(2); + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Dispatchlist/DispatchpicklistEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Dispatchlist/DispatchpicklistEntity.cs new file mode 100644 index 0000000..e7affb3 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Dispatchlist/DispatchpicklistEntity.cs @@ -0,0 +1,76 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// dispatchpicklist entity + /// + [Table("dispatchpicklist")] + public class DispatchpicklistEntity : BaseModel + { + #region foreign table + + /// + /// foreign table + /// + [ForeignKey("dispatchlist_id")] + public DispatchlistEntity Dispatchlist { get; set; } + + #endregion + + #region Property + + /// + /// dispatchlist_id + /// + public int dispatchlist_id { get; set; } = 0; + + /// + /// goods_owner_id + /// + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_location_id + /// + public int goods_location_id { get; set; } = 0; + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// pick_qty + /// + public int pick_qty { get; set; } = 0; + + /// + /// picked_qty + /// + public int picked_qty { get; set; } = 0; + + /// + /// is_update_stock + /// + public bool is_update_stock { get; set; } = false; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Freightfee/FreightfeeEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Freightfee/FreightfeeEntity.cs new file mode 100644 index 0000000..9685932 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Freightfee/FreightfeeEntity.cs @@ -0,0 +1,82 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// freightfee entity + /// + [Table("freightfee")] + public class FreightfeeEntity : BaseModel + { + + #region Property + + /// + /// carrier + /// + public string carrier { get; set; } = string.Empty; + + /// + /// departure_city + /// + public string departure_city { get; set; } = string.Empty; + + /// + /// arrival_city + /// + public string arrival_city { get; set; } = string.Empty; + + /// + /// price_per_weight + /// + public decimal price_per_weight { get; set; } = 0; + + /// + /// price_per_volume + /// + public decimal price_per_volume { get; set; } = 0; + + /// + /// min_payment + /// + public decimal min_payment { get; set; } = 0; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// is_valid + /// + public bool is_valid { get; set; } = false; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/GoodsOwner/GoodsownerEntity.cs b/backend/ModernWMS.WMS/Entities/Models/GoodsOwner/GoodsownerEntity.cs new file mode 100644 index 0000000..6307513 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/GoodsOwner/GoodsownerEntity.cs @@ -0,0 +1,64 @@ +using ModernWMS.Core.Models; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// goods owner entity + /// + [Table("goodsowner")] + public class GoodsownerEntity : BaseModel + { + #region Property + /// + /// goods owner name + /// + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// city + /// + public string city { get; set; } = string.Empty; + + /// + /// address + /// + public string address { get; set; } = string.Empty; + + /// + /// manager + /// + public string manager { get; set; } = string.Empty; + + /// + /// contact tel + /// + public string contact_tel { get; set; } = string.Empty; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create time + /// + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last update time + /// + public DateTime last_update_time { get; set; } = DateTime.Now; + + /// + /// valid + /// + public bool is_valid { get; set; } = true; + + /// + /// the tenant id + /// + public long tenant_id { get; set; } = 1; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Goodslocation/GoodslocationEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Goodslocation/GoodslocationEntity.cs new file mode 100644 index 0000000..dcc56c4 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Goodslocation/GoodslocationEntity.cs @@ -0,0 +1,122 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// goodslocation entity + /// + [Table("goodslocation")] + public class GoodslocationEntity : BaseModel + { + + #region Property + + /// + /// warehouse_id + /// + public int warehouse_id { get; set; } = 0; + + /// + /// warehouse_name + /// + public string warehouse_name { get; set; } = string.Empty; + + /// + /// warehouse_area_name + /// + public string warehouse_area_name { get; set; } = string.Empty; + + /// + /// warehouse_area_property + /// + public byte warehouse_area_property { get; set; } = 0; + + /// + /// location_name + /// + public string location_name { get; set; } = string.Empty; + + /// + /// location_length + /// + public decimal location_length { get; set; } = 0; + + /// + /// location_width + /// + public decimal location_width { get; set; } = 0; + + /// + /// location_heigth + /// + public decimal location_heigth { get; set; } = 0; + + /// + /// location_volume + /// + public decimal location_volume { get; set; } = 0; + + /// + /// location_load + /// + public decimal location_load { get; set; } = 0; + + /// + /// roadway_number + /// + public string roadway_number { get; set; } = string.Empty; + + /// + /// shelf_number + /// + public string shelf_number { get; set; } = string.Empty; + + /// + /// layer_number + /// + public string layer_number { get; set; } = string.Empty; + + /// + /// tag_number + /// + public string tag_number { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// is_valid + /// + public bool is_valid { get; set; } = false; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + /// + /// warehouse_area_id + /// + public int warehouse_area_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Rolemenu/MenuEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Rolemenu/MenuEntity.cs new file mode 100644 index 0000000..0bb4d2b --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Rolemenu/MenuEntity.cs @@ -0,0 +1,54 @@ +using ModernWMS.Core.Models; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// menu entity + /// + [Table("menu")] + public class MenuEntity : BaseModel + { + + #region Property + + /// + /// menu_name + /// + public string menu_name { get; set; } = string.Empty; + + /// + /// module + /// + public string module { get; set; } = string.Empty; + + /// + /// vue_path + /// + public string vue_path { get; set; } = string.Empty; + + /// + /// vue_path_detail + /// + public string vue_path_detail { get; set; } = string.Empty; + + /// + /// vue_directory + /// + public string vue_directory { get; set; } = string.Empty; + + /// + /// sort + /// + public int sort { get; set; } = 0; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 1; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Rolemenu/RolemenuEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Rolemenu/RolemenuEntity.cs new file mode 100644 index 0000000..c7d8d13 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Rolemenu/RolemenuEntity.cs @@ -0,0 +1,57 @@ +/* + * date:2022-12-20 + * developer:AMo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// rolemenu entity + /// + [Table("rolemenu")] + public class RolemenuEntity : BaseModel + { + + #region Property + + /// + /// userrole_id + /// + public int userrole_id { get; set; } = 0; + + /// + /// menu_id + /// + public int menu_id { get; set; } = 0; + + /// + /// authority + /// + public byte authority { get; set; } = 1; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 1; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Sku/CategoryEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Sku/CategoryEntity.cs new file mode 100644 index 0000000..83d5203 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Sku/CategoryEntity.cs @@ -0,0 +1,59 @@ +/* + * date:2022-12-20 + * developer:AMo + */ +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// category entity + /// + [Table("category")] + public class CategoryEntity : BaseModel + { + + #region Property + + /// + /// category_name + /// + public string category_name { get; set; } = string.Empty; + + /// + /// parent_id + /// + public int parent_id { get; set; } = 0; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// is_valid + /// + public bool is_valid { get; set; } = true; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 1; + + + #endregion + + } +} \ No newline at end of file diff --git a/backend/ModernWMS.WMS/Entities/Models/Sku/SkuEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Sku/SkuEntity.cs new file mode 100644 index 0000000..fe4aa02 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Sku/SkuEntity.cs @@ -0,0 +1,100 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// sku entity + /// + [Table("sku")] + public class SkuEntity : BaseModel + { + #region navigational properties + /// + /// navigational properties + /// + [ForeignKey("spu_id")] + public SpuEntity Spu { get; set; } + + #endregion + + #region Property + + /// + /// spu_id + /// + public int spu_id { get; set; } = 0; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// sku_name + /// + public string sku_name { get; set; } = string.Empty; + + /// + /// weight + /// + public decimal weight { get; set; } = 0; + + /// + /// lenght + /// + public decimal lenght { get; set; } = 0; + + /// + /// width + /// + public decimal width { get; set; } = 0; + + /// + /// height + /// + public decimal height { get; set; } = 0; + + /// + /// volume + /// + public decimal volume { get; set; } = 0; + + /// + /// unit + /// + public string unit { get; set; } = string.Empty; + + /// + /// cost + /// + public decimal cost { get; set; } = 0; + + /// + /// price + /// + public decimal price { get; set; } = 0; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + + #endregion + + } +} \ No newline at end of file diff --git a/backend/ModernWMS.WMS/Entities/Models/Sku/SpuEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Sku/SpuEntity.cs new file mode 100644 index 0000000..f5f3f54 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Sku/SpuEntity.cs @@ -0,0 +1,118 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// spu entity + /// + [Table("spu")] + public class SpuEntity : BaseModel + { + + #region Property + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// category_id + /// + public int category_id { get; set; } = 0; + + /// + /// spu_description + /// + public string spu_description { get; set; } = string.Empty; + + /// + /// bar_code + /// + public string bar_code { get; set; } = string.Empty; + + /// + /// supplier_id + /// + public int supplier_id { get; set; } = 0; + + /// + /// supplier_name + /// + public string supplier_name { get; set; } = string.Empty; + + /// + /// brand + /// + public string brand { get; set; } = string.Empty; + + /// + /// origin + /// + public string origin { get; set; } = string.Empty; + + /// + /// length_unit + /// + public byte length_unit { get; set; } = 0; + + /// + /// volume_unit + /// + public byte volume_unit { get; set; } = 0; + + /// + /// weight_unit + /// + public byte weight_unit { get; set; } = 0; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = DateTime.Now; + + /// + /// is_valid + /// + public bool is_valid { get; set; } = true; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 1; + + + #endregion + + #region details + /// + /// sku + /// + public List detailList { get; set; } = new List(); + #endregion + } +} \ No newline at end of file diff --git a/backend/ModernWMS.WMS/Entities/Models/Stock/StockEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Stock/StockEntity.cs new file mode 100644 index 0000000..c9d3512 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Stock/StockEntity.cs @@ -0,0 +1,63 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// stock entity + /// + [Table("stock")] + public class StockEntity : BaseModel + { + + #region Property + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// goods_location_id + /// + public int goods_location_id { get; set; } = 0; + + /// + /// qty + /// + public int qty { get; set; } = 0; + + /// + /// goods_owner_id + /// + public int goods_owner_id { get; set; } = 0; + + /// + /// is_freeze + /// + public bool is_freeze { get; set; } = false; + + /// + /// last_update_time + /// + [ConcurrencyCheck] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Stockadjust/StockadjustEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Stockadjust/StockadjustEntity.cs new file mode 100644 index 0000000..7ae8fd4 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Stockadjust/StockadjustEntity.cs @@ -0,0 +1,87 @@ +/* + * date:2022-12-26 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// stockadjust entity + /// + [Table("stockadjust")] + public class StockadjustEntity : BaseModel + { + + #region Property + + /// + /// job_code + /// + public string job_code { get; set; } = string.Empty; + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// goods_owner_id + /// + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_location_id + /// + public int goods_location_id { get; set; } = 0; + + /// + /// qty + /// + public int qty { get; set; } = 0; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + /// + /// is_update_stock + /// + public bool is_update_stock { get; set; } = false; + + /// + /// job_type + /// + public byte job_type { get; set; } = 0; + + /// + /// source_table_id + /// + public int source_table_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Stockfreeze/StockfreezeEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Stockfreeze/StockfreezeEntity.cs new file mode 100644 index 0000000..dfe13b3 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Stockfreeze/StockfreezeEntity.cs @@ -0,0 +1,72 @@ +/* + * date:2022-12-26 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// stockfreeze entity + /// + [Table("stockfreeze")] + public class StockfreezeEntity : BaseModel + { + + #region Property + + /// + /// job_code + /// + public string job_code { get; set; } = string.Empty; + + /// + /// job_type + /// + public bool job_type { get; set; } = false; + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// goods_owner_id + /// + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_location_id + /// + public int goods_location_id { get; set; } = 0; + + /// + /// handler + /// + public string handler { get; set; } = string.Empty; + + /// + /// operate_time + /// + public DateTime handle_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Stockmove/StockmoveEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Stockmove/StockmoveEntity.cs new file mode 100644 index 0000000..67d0384 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Stockmove/StockmoveEntity.cs @@ -0,0 +1,92 @@ +/* + * date:2022-12-27 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// stockmove entity + /// + [Table("stockmove")] + public class StockmoveEntity : BaseModel + { + + #region Property + + /// + /// job_code + /// + public string job_code { get; set; } = string.Empty; + + /// + /// move_status + /// + public byte move_status { get; set; } = 0; + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// orig_goods_location_id + /// + public int orig_goods_location_id { get; set; } = 0; + + /// + /// dest_googs_location_id + /// + public int dest_googs_location_id { get; set; } = 0; + + /// + /// qty + /// + public int qty { get; set; } = 0; + + /// + /// goods_owner_id + /// + public int goods_owner_id { get; set; } = 0; + + /// + /// handler + /// + public string handler { get; set; } = string.Empty; + + /// + /// handle_time + /// + public DateTime handle_time { get; set; } = UtilConvert.MinDate; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Stockprocess/StockprocessEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Stockprocess/StockprocessEntity.cs new file mode 100644 index 0000000..8471325 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Stockprocess/StockprocessEntity.cs @@ -0,0 +1,82 @@ +/* + * date:2022-12-23 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// stockprocess entity + /// + [Table("stockprocess")] + public class StockprocessEntity : BaseModel + { + + #region Property + + /// + /// job_code + /// + public string job_code { get; set; } = string.Empty; + + /// + /// job_type + /// + public bool job_type { get; set; } = false; + + /// + /// process_status + /// + public bool process_status { get; set; } = false; + + /// + /// processor + /// + public string processor { get; set; } = string.Empty; + + /// + /// process_time + /// + public DateTime process_time { get; set; } = UtilConvert.MinDate; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + + #endregion + + + #region detail table + + /// + /// detail table + /// + public List detailList { get; set; } = new List(2); + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Stockprocess/StockprocessdetailEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Stockprocess/StockprocessdetailEntity.cs new file mode 100644 index 0000000..9efbf6a --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Stockprocess/StockprocessdetailEntity.cs @@ -0,0 +1,79 @@ +/* + * date:2022-12-23 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// stockprocessdetail entity + /// + [Table("stockprocessdetail")] + public class StockprocessdetailEntity : BaseModel + { + #region foreign table + + /// + /// foreign table + /// + [ForeignKey("stock_process_id")] + public StockprocessEntity Stockprocess { get; set; } + + #endregion + + #region Property + + /// + /// stock_process_id + /// + public int stock_process_id { get; set; } = 0; + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// goods_owner_id + /// + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_location_id + /// + public int goods_location_id { get; set; } = 0; + + /// + /// qty + /// + public int qty { get; set; } = 0; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + /// + /// is_source + /// + public bool is_source { get; set; } = false; + + /// + /// is_update_stock + /// + public bool is_update_stock { get; set; } = false; + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Stocktaking/StocktakingEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Stocktaking/StocktakingEntity.cs new file mode 100644 index 0000000..d709f74 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Stocktaking/StocktakingEntity.cs @@ -0,0 +1,96 @@ +/* + * date:2022-12-30 + * developer:AMo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// stocktaking entity + /// + [Table("stocktaking")] + public class StocktakingEntity : BaseModel + { + + #region Property + + /// + /// job_code + /// + public string job_code { get; set; } = string.Empty; + + /// + /// job_status + /// + public bool job_status { get; set; } = false; + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// goods_owner_id + /// + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_location_id + /// + public int goods_location_id { get; set; } = 0; + + /// + /// book_qty + /// + public int book_qty { get; set; } = 0; + + /// + /// counted_qty + /// + public int counted_qty { get; set; } = 0; + + /// + /// difference_qty + /// + public int difference_qty { get; set; } = 0; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = DateTime.Now; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 1; + + /// + /// handler + /// + public string handler { get; set; } = string.Empty; + + /// + /// handle_time + /// + public DateTime handle_time { get; set; } = UtilConvert.MinDate; + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Warehouse/WarehouseEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Warehouse/WarehouseEntity.cs new file mode 100644 index 0000000..317378e --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Warehouse/WarehouseEntity.cs @@ -0,0 +1,82 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// warehouse entity + /// + [Table("warehouse")] + public class WarehouseEntity : BaseModel + { + + #region Property + + /// + /// warehouse_name + /// + public string warehouse_name { get; set; } = string.Empty; + + /// + /// city + /// + public string city { get; set; } = string.Empty; + + /// + /// address + /// + public string address { get; set; } = string.Empty; + + /// + /// email + /// + public string email { get; set; } = string.Empty; + + /// + /// manager + /// + public string manager { get; set; } = string.Empty; + + /// + /// contact_tel + /// + public string contact_tel { get; set; } = string.Empty; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// is_valid + /// + public bool is_valid { get; set; } = false; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/Warehousearea/WarehouseareaEntity.cs b/backend/ModernWMS.WMS/Entities/Models/Warehousearea/WarehouseareaEntity.cs new file mode 100644 index 0000000..a1583ef --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/Warehousearea/WarehouseareaEntity.cs @@ -0,0 +1,67 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// warehousearea entity + /// + [Table("warehousearea")] + public class WarehouseareaEntity : BaseModel + { + + #region Property + + /// + /// warehouse_id + /// + public int warehouse_id { get; set; } = 0; + + /// + /// area_name + /// + public string area_name { get; set; } = string.Empty; + + /// + /// parent_id + /// + public int parent_id { get; set; } = 0; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// is_valid + /// + public bool is_valid { get; set; } = false; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + /// + /// area_property + /// + public byte area_property { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/company/CompanyEntity.cs b/backend/ModernWMS.WMS/Entities/Models/company/CompanyEntity.cs new file mode 100644 index 0000000..3318742 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/company/CompanyEntity.cs @@ -0,0 +1,52 @@ +using ModernWMS.Core.Models; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// company entity + /// + [Table("company")] + public class CompanyEntity: BaseModel + { + /// + /// company's Name + /// + public string company_name { get; set; } = string.Empty; + + /// + /// city + /// + public string city { get; set; } = string.Empty; + + /// + /// address + /// + public string address { get; set; } = string.Empty; + + /// + /// manager + /// + public string manager { get; set; } = string.Empty; + + /// + /// contact tel + /// + public string contact_tel { get; set; } = string.Empty; + + /// + /// create time + /// + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last update time + /// + public DateTime last_update_time { get; set; } = DateTime.Now; + + /// + /// the tenant id + /// + public long tenant_id { get; set; } = 1; + } +} diff --git a/backend/ModernWMS.WMS/Entities/Models/supplier/SupplierEntity.cs b/backend/ModernWMS.WMS/Entities/Models/supplier/SupplierEntity.cs new file mode 100644 index 0000000..d498cd4 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/Models/supplier/SupplierEntity.cs @@ -0,0 +1,82 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Models; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.Models +{ + /// + /// supplier entity + /// + [Table("supplier")] + public class SupplierEntity : BaseModel + { + + #region Property + + /// + /// supplier_name + /// + public string supplier_name { get; set; } = string.Empty; + + /// + /// city + /// + public string city { get; set; } = string.Empty; + + /// + /// address + /// + public string address { get; set; } = string.Empty; + + /// + /// email + /// + public string email { get; set; } = string.Empty; + + /// + /// manager + /// + public string manager { get; set; } = string.Empty; + + /// + /// contact_tel + /// + public string contact_tel { get; set; } = string.Empty; + + /// + /// creator + /// + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// is_valid + /// + public bool is_valid { get; set; } = false; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Asn/AsnBulkModifyGoodsOwnerViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/AsnBulkModifyGoodsOwnerViewModel.cs new file mode 100644 index 0000000..38dd018 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/AsnBulkModifyGoodsOwnerViewModel.cs @@ -0,0 +1,48 @@ +/* + * date:2022-12-22 + * developer:AMo + */ +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// asn bulk modify goods owner input view model + /// + public class AsnBulkModifyGoodsOwnerViewModel + { + #region constructor + /// + /// constructor + /// + public AsnBulkModifyGoodsOwnerViewModel() + { + + } + #endregion + + #region Property + + /// + /// goods_owner_id + /// + [Display(Name = "goods_owner_id")] + [Required(ErrorMessage = "Required")] + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_owner_name + /// + [Display(Name = "goods_owner_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// selected asn id + /// + public List idList { get; set; } = new List(); + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Asn/AsnViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/AsnViewModel.cs new file mode 100644 index 0000000..a997a8c --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/AsnViewModel.cs @@ -0,0 +1,218 @@ +/* + * date:2022-12-22 + * developer:AMo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// asn viewModel + /// + public class AsnViewModel + { + + #region constructor + /// + /// constructor + /// + public AsnViewModel() + { + + } + #endregion + + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// asn_no + /// + [Display(Name = "asn_no")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string asn_no { get; set; } = string.Empty; + + /// + /// asn_status + /// + [Display(Name = "asn_status")] + public byte asn_status { get; set; } = 0; + + /// + /// spu_id + /// + [Display(Name = "spu_id")] + [Required(ErrorMessage = "Required")] + public int spu_id { get; set; } = 0; + + /// + /// spu_code + /// + [Display(Name = "spu_code")] + [Required(ErrorMessage = "Required")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + [Display(Name = "spu_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(200, ErrorMessage = "MaxLength")] + public string spu_name { get; set; } = string.Empty; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// sku_code + /// + [Display(Name = "sku_code")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string sku_code { get; set; } = string.Empty; + + /// + /// sku_name + /// + [Display(Name = "sku_name")] + [MaxLength(200, ErrorMessage = "MaxLength")] + public string sku_name { get; set; } = string.Empty; + + /// + /// origin + /// + [Display(Name = "origin")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string origin { get; set; } = string.Empty; + + /// + /// length_unit (0=毫米、1=厘米、2=分米、3=米) + /// + [Display(Name = "length_unit")] + public byte length_unit { get; set; } = 0; + + /// + /// volume_unit (0=立方厘米、1=立方分米、2=立方米) + /// + [Display(Name = "volume_unit")] + public byte volume_unit { get; set; } = 0; + + /// + /// weight_unit (0=毫克、1=克、2=千克) + /// + [Display(Name = "weight_unit")] + public byte weight_unit { get; set; } = 0; + + /// + /// asn_qty + /// + [Display(Name = "asn_qty")] + public int asn_qty { get; set; } = 0; + + /// + /// actual_qty + /// + [Display(Name = "actual_qty")] + public int actual_qty { get; set; } = 0; + + /// + /// sorted_qty + /// + [Display(Name = "sorted_qty")] + public int sorted_qty { get; set; } = 0; + + /// + /// shortage_qty + /// + [Display(Name = "shortage_qty")] + public int shortage_qty { get; set; } = 0; + + /// + /// more_qty + /// + [Display(Name = "more_qty")] + public int more_qty { get; set; } = 0; + + /// + /// damage_qty + /// + [Display(Name = "damage_qty")] + public int damage_qty { get; set; } = 0; + + /// + /// weight + /// + [Display(Name = "weight")] + public decimal weight { get; set; } = 0; + + /// + /// volume + /// + [Display(Name = "volume")] + public decimal volume { get; set; } = 0; + + /// + /// supplier_id + /// + [Display(Name = "supplier_id")] + public int supplier_id { get; set; } = 0; + + /// + /// supplier_name + /// + [Display(Name = "supplier_name")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string supplier_name { get; set; } = string.Empty; + + /// + /// goods_owner_id + /// + [Display(Name = "goods_owner_id")] + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_owner_name + /// + [Display(Name = "goods_owner_name")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + public DateTime last_update_time { get; set; } = DateTime.Now; + + /// + /// is_valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } = true; + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnFlowInputViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnFlowInputViewModel.cs new file mode 100644 index 0000000..63c2cb3 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnFlowInputViewModel.cs @@ -0,0 +1,36 @@ +/* + * date:2022-12-22 + * developer:AMo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// asn flow input viewModel + /// + public class AsnFlowInputViewModel + { + #region constructor + /// + /// constructor + /// + public AsnFlowInputViewModel() + { + + } + #endregion + + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnPutAwayInputViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnPutAwayInputViewModel.cs new file mode 100644 index 0000000..20c45e5 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnPutAwayInputViewModel.cs @@ -0,0 +1,48 @@ +/* + * date:2022-12-30 + * developer:AMo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// asn put away input viewModel + /// + public class AsnPutAwayInputViewModel + { + #region constructor + /// + /// constructor + /// + public AsnPutAwayInputViewModel() + { + + } + #endregion + + #region Property + + /// + /// asn_id + /// + [Display(Name = "asn_id")] + public int asn_id { get; set; } = 0; + + /// + /// goods_location_id + /// + [Display(Name = "goods_location_id")] + public int goods_location_id { get; set; } = 0; + + /// + /// putaway_qty + /// + [Display(Name = "putaway_qty")] + public int putaway_qty { get; set; } = 0; + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnsortInputViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnsortInputViewModel.cs new file mode 100644 index 0000000..0bf1181 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnsortInputViewModel.cs @@ -0,0 +1,42 @@ +/* + * date:2022-12-30 + * developer:AMo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// asn sorting input viewModel + /// + public class AsnsortInputViewModel + { + #region constructor + /// + /// constructor + /// + public AsnsortInputViewModel() + { + + } + #endregion + + #region Property + + /// + /// asn_id + /// + [Display(Name = "asn_id")] + public int asn_id { get; set; } = 0; + + /// + /// sorted_qty + /// + [Display(Name = "sorted_qty")] + public int sorted_qty { get; set; } = 0; + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Customer/CustomerImportViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Customer/CustomerImportViewModel.cs new file mode 100644 index 0000000..16ed8e6 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Customer/CustomerImportViewModel.cs @@ -0,0 +1,80 @@ +/* + * date:2023-01-04 + * developer:AMo + */ +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// customer import view model + /// + public class CustomerImportViewModel + { + #region constructor + /// + /// constructor + /// + public CustomerImportViewModel() + { + + } + #endregion + + #region Property + + /// + /// customer's name + /// + [Display(Name = "customer_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string customer_name { get; set; } = string.Empty; + + /// + /// city + /// + [Display(Name = "city")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string city { get; set; } = string.Empty; + + /// + /// address + /// + [Display(Name = "address")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string address { get; set; } = string.Empty; + + /// + /// manager + /// + [Display(Name = "manager")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string manager { get; set; } = string.Empty; + + /// + /// email + /// + [Display(Name = "email")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string email { get; set; } = string.Empty; + + /// + /// contact tel + /// + [Display(Name = "contact_tel")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string contact_tel { get; set; } = string.Empty; + + /// + /// _XID + /// + public string _XID { get; set; } = string.Empty; + + /// + /// error message + /// + public string errorMsg { get; set; } = string.Empty; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Customer/CustomerViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Customer/CustomerViewModel.cs new file mode 100644 index 0000000..7e36946 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Customer/CustomerViewModel.cs @@ -0,0 +1,102 @@ +/* + * date:2023-01-04 + * developer:AMo + */ +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// customer view model + /// + public class CustomerViewModel + { + #region constructor + /// + /// constructor + /// + public CustomerViewModel() + { + + } + #endregion + + #region Property + + /// + /// primary key + /// + public int id { get; set; } = 0; + + /// + /// customer's name + /// + [Display(Name = "customer_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string customer_name { get; set; } = string.Empty; + + /// + /// city + /// + [Display(Name = "city")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string city { get; set; } = string.Empty; + + /// + /// address + /// + [Display(Name = "address")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string address { get; set; } = string.Empty; + + /// + /// manager + /// + [Display(Name = "manager")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string manager { get; set; } = string.Empty; + + /// + /// email + /// + [Display(Name = "email")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string email { get; set; } = string.Empty; + + /// + /// contact tel + /// + [Display(Name = "contact_tel")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string contact_tel { get; set; } = string.Empty; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last update time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = DateTime.Now; + + /// + /// valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } = true; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/CancelOrderOprationViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/CancelOrderOprationViewModel.cs new file mode 100644 index 0000000..64d5aae --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/CancelOrderOprationViewModel.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// what should be inputed when canceling order opration + /// + public class CancelOrderOprationViewModel + { + #region constructor + /// + /// CancleOrderOprationViewModel + /// + public CancelOrderOprationViewModel() + { + + } + #endregion + #region Property + /// + /// dispatch_no + /// + public string dispatch_no { get; set; } = string.Empty; + + /// + /// dispatch_status + /// + public int dispatch_status { get; set; } = 0; + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistAddViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistAddViewModel.cs new file mode 100644 index 0000000..2eba038 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistAddViewModel.cs @@ -0,0 +1,59 @@ +/* + * date:2022-12-29 + * developer:NoNo + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// add dispatchlist viewmodel + /// + public class DispatchlistAddViewModel + { + #region constructor + /// + /// constructor + /// + public DispatchlistAddViewModel() + { + + } + #endregion + #region Property + /// + /// customer_id + /// + public int customer_id { get; set; } = 0; + + /// + /// customer_name + /// + public string customer_name { get; set; } = string.Empty; + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// qty + /// + public int qty { get; set; } = 0; + + /// + /// weight + /// + public decimal weight { get; set; } = 0; + + /// + /// volume + /// + public decimal volume { get; set; } = 0; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistConfirmDetailViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistConfirmDetailViewModel.cs new file mode 100644 index 0000000..e5eab5e --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistConfirmDetailViewModel.cs @@ -0,0 +1,111 @@ + +using ModernWMS.Core.Utility; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + public class DispatchlistConfirmDetailViewModel + { + #region constructor + /// + /// constructor + /// + public DispatchlistConfirmDetailViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int dispatchlist_id { get; set; } = 0; + + /// + /// dispatch_no + /// + [Display(Name = "dispatch_no")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string dispatch_no { get; set; } = string.Empty; + + /// + /// dispatch_status + /// + [Display(Name = "dispatch_status")] + public byte dispatch_status { get; set; } = 0; + + /// + /// customer_id + /// + [Display(Name = "customer_id")] + public int customer_id { get; set; } = 0; + + /// + /// customer_name + /// + [Display(Name = "customer_name")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string customer_name { get; set; } = string.Empty; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// qty + /// + [Display(Name = "qty")] + public int qty { get; set; } = 0; + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// spu_description + /// + public string spu_description { get; set; } = string.Empty; + + /// + /// bar_code + /// + public string bar_code { get; set; } = string.Empty; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// quantity available + /// + public int qty_available { get; set; } = 0; + + /// + /// confirm order + /// + public bool confirm { get; set; } = false; + + /// + /// pick list + /// + public List pick_list { get; set; } = new List(); + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistConfirmPickDetailViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistConfirmPickDetailViewModel.cs new file mode 100644 index 0000000..d5c1d94 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistConfirmPickDetailViewModel.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + public class DispatchlistConfirmPickDetailViewModel + { + #region constructor + /// + /// constructor + /// + public DispatchlistConfirmPickDetailViewModel() + { + + } + #endregion + #region Property + /// + /// stock_id + /// + public int stock_id { get; set; } = 0; + + /// + /// dispatchlist_id + /// + public int dispatchlist_id { get; set; } = 0; + + /// + /// goods_owner_id + /// + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_owner_name + /// + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// goods_location_id + /// + public int goods_location_id { get; set; } = 0; + + /// + /// warehouse_name + /// + public string warehouse_name { get; set; } = string.Empty; + + /// + /// location_name + /// + public string location_name { get; set; } = string.Empty; + + /// + /// warehouse_area_name + /// + public string warehouse_area_name { get; set; } = string.Empty; + + + /// + /// quantity available + /// + public int qty_available { get; set; } = 0; + + /// + /// pick_qty + /// + public int pick_qty { get; set; } = 0; + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistDeliveryViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistDeliveryViewModel.cs new file mode 100644 index 0000000..87fda87 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistDeliveryViewModel.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// DispatchlistStockOutViewModel + /// + public class DispatchlistDeliveryViewModel + { + #region constructor + /// + /// constructor + /// + public DispatchlistDeliveryViewModel() + { + + } + #endregion + #region Property + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// dispatch_no + /// + [Display(Name = "dispatch_no")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string dispatch_no { get; set; } = string.Empty; + + /// + /// dispatch_status + /// + [Display(Name = "dispatch_status")] + public byte dispatch_status { get; set; } = 0; + + /// + /// picked_qty + /// + [Display(Name = "picked_qty")] + public int picked_qty { get; set; } = 0; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistDetailViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistDetailViewModel.cs new file mode 100644 index 0000000..21dd0db --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistDetailViewModel.cs @@ -0,0 +1,230 @@ +using ModernWMS.Core.Utility; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + public class DispatchlistDetailViewModel + { + #region constructor + /// + /// constructor + /// + public DispatchlistDetailViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// dispatch_no + /// + [Display(Name = "dispatch_no")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string dispatch_no { get; set; } = string.Empty; + + /// + /// dispatch_status + /// + [Display(Name = "dispatch_status")] + public byte dispatch_status { get; set; } = 0; + + /// + /// customer_id + /// + [Display(Name = "customer_id")] + public int customer_id { get; set; } = 0; + + /// + /// customer_name + /// + [Display(Name = "customer_name")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string customer_name { get; set; } = string.Empty; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// qty + /// + [Display(Name = "qty")] + public int qty { get; set; } = 0; + + /// + /// weight + /// + [Display(Name = "weight")] + public decimal weight { get; set; } = 0; + + /// + /// volume + /// + [Display(Name = "volume")] + public decimal volume { get; set; } = 0; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// damage_qty + /// + [Display(Name = "damage_qty")] + public int damage_qty { get; set; } = 0; + + /// + /// lock_qty + /// + [Display(Name = "lock_qty")] + public int lock_qty { get; set; } = 0; + + /// + /// picked_qty + /// + [Display(Name = "picked_qty")] + public int picked_qty { get; set; } = 0; + + /// + /// intrasit_qty + /// + [Display(Name = "intrasit_qty")] + public int intrasit_qty { get; set; } = 0; + + /// + /// package_qty + /// + [Display(Name = "package_qty")] + public int package_qty { get; set; } = 0; + + /// + /// weighing_qty + /// + [Display(Name = "weighing_qty")] + public int weighing_qty { get; set; } = 0; + + /// + /// actual_qty + /// + [Display(Name = "actual_qty")] + public int actual_qty { get; set; } = 0; + + /// + /// sign_qty + /// + [Display(Name = "sign_qty")] + public int sign_qty { get; set; } = 0; + + /// + /// package_no + /// + [Display(Name = "package_no")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string package_no { get; set; } = string.Empty; + + /// + /// package_person + /// + [Display(Name = "package_person")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string package_person { get; set; } = string.Empty; + + /// + /// package_time + /// + [Display(Name = "package_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime package_time { get; set; } = UtilConvert.MinDate; + + /// + /// weighing_no + /// + [Display(Name = "weighing_no")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string weighing_no { get; set; } = string.Empty; + + /// + /// weighing_person + /// + [Display(Name = "weighing_person")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string weighing_person { get; set; } = string.Empty; + + /// + /// weighing_weight + /// + [Display(Name = "weighing_weight")] + public decimal weighing_weight { get; set; } = 0; + + /// + /// waybill_no + /// + [Display(Name = "waybill_no")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string waybill_no { get; set; } = string.Empty; + + /// + /// carrier + /// + [Display(Name = "carrier")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string carrier { get; set; } = string.Empty; + + /// + /// freightfee + /// + [Display(Name = "freightfee")] + public decimal freightfee { get; set; } = 0; + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// spu_description + /// + public string spu_description { get; set; } = string.Empty; + + /// + /// bar_code + /// + public string bar_code { get; set; } = string.Empty; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistFreightfeeViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistFreightfeeViewModel.cs new file mode 100644 index 0000000..661596c --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistFreightfeeViewModel.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// DispatchlistFreightfeeViewModel + /// + public class DispatchlistFreightfeeViewModel + { + #region constructor + /// + /// constructor + /// + public DispatchlistFreightfeeViewModel() + { + + } + #endregion + #region Property + [Display(Name = "id")] + public int id { get; set; } = 0; + /// + /// dispatch_no + /// + [Display(Name = "dispatch_no")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string dispatch_no { get; set; } = string.Empty; + + /// + /// dispatch_status + /// + [Display(Name = "dispatch_status")] + public byte dispatch_status { get; set; } = 0; + + /// + /// freightfee_id + /// + [Display(Name = "freightfee_id")] + public int freightfee_id { get; set; } = 0; + + /// + /// carrier + /// + [Display(Name = "carrier")] + [MaxLength(256, ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string carrier { get; set; } = string.Empty; + + /// + /// waybill_no + /// + public string waybill_no { get; set; } = string.Empty; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistPackageViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistPackageViewModel.cs new file mode 100644 index 0000000..c3a29f7 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistPackageViewModel.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// DispatchlistPackageViewModel + /// + public class DispatchlistPackageViewModel + { + #region constructor + /// + /// constructor + /// + public DispatchlistPackageViewModel() + { + + } + #endregion + #region Property + [Display(Name = "id")] + public int id { get; set; } = 0; + /// + /// dispatch_no + /// + [Display(Name = "dispatch_no")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string dispatch_no { get; set; } = string.Empty; + + /// + /// dispatch_status + /// + [Display(Name = "dispatch_status")] + public byte dispatch_status { get; set; } = 0; + /// + /// package_qty + /// + [Display(Name = "package_qty")] + public int package_qty { get; set; } = 0; + + /// + /// picked_qty + /// + [Display(Name = "picked_qty")] + public int picked_qty { get; set; } = 0; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistSignViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistSignViewModel.cs new file mode 100644 index 0000000..47f9f30 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistSignViewModel.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// DispatchlistSignViewModel + /// + public class DispatchlistSignViewModel + { + #region constructor + /// + /// constructor + /// + public DispatchlistSignViewModel() + { + + } + #endregion + #region Property + [Display(Name = "id")] + public int id { get; set; } = 0; + /// + /// dispatch_no + /// + [Display(Name = "dispatch_no")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string dispatch_no { get; set; } = string.Empty; + + /// + /// dispatch_status + /// + [Display(Name = "dispatch_status")] + public byte dispatch_status { get; set; } = 0; + + /// + /// damage_qty + /// + public int damage_qty { get; set; } = 0; + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistViewModel.cs new file mode 100644 index 0000000..efac5d3 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistViewModel.cs @@ -0,0 +1,281 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// dispatchlist viewModel + /// + public class DispatchlistViewModel + { + + #region constructor + /// + /// constructor + /// + public DispatchlistViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// dispatch_no + /// + [Display(Name = "dispatch_no")] + [MaxLength(32,ErrorMessage = "MaxLength")] + public string dispatch_no { get; set; } = string.Empty; + + /// + /// dispatch_status + /// + [Display(Name = "dispatch_status")] + public byte dispatch_status { get; set; } = 0; + + /// + /// customer_id + /// + [Display(Name = "customer_id")] + public int customer_id { get; set; } = 0; + + /// + /// customer_name + /// + [Display(Name = "customer_name")] + [MaxLength(256,ErrorMessage = "MaxLength")] + public string customer_name { get; set; } = string.Empty; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// qty + /// + [Display(Name = "qty")] + public int qty { get; set; } = 0; + + /// + /// weight + /// + [Display(Name = "weight")] + public decimal weight { get; set; } = 0; + + /// + /// volume + /// + [Display(Name = "volume")] + public decimal volume { get; set; } = 0; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64,ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// damage_qty + /// + [Display(Name = "damage_qty")] + public int damage_qty { get; set; } = 0; + + /// + /// lock_qty + /// + [Display(Name = "lock_qty")] + public int lock_qty { get; set; } = 0; + + /// + /// picked_qty + /// + [Display(Name = "picked_qty")] + public int picked_qty { get; set; } = 0; + + /// + /// unpicked_qty + /// + [Display(Name = "unpicked_qty")] + public int unpicked_qty { get; set; } = 0; + + /// + /// intrasit_qty + /// + [Display(Name = "intrasit_qty")] + public int intrasit_qty { get; set; } = 0; + + /// + /// package_qty + /// + [Display(Name = "package_qty")] + public int package_qty { get; set; } = 0; + + /// + /// unpackage_qty + /// + [Display(Name = "unpackage_qty")] + public int unpackage_qty { get; set; } = 0; + + /// + /// weighing_qty + /// + [Display(Name = "weighing_qty")] + public int weighing_qty { get; set; } = 0; + + /// + /// weighing_qty + /// + [Display(Name = "unweighing_qty")] + public int unweighing_qty { get; set; } = 0; + + /// + /// actual_qty + /// + [Display(Name = "actual_qty")] + public int actual_qty { get; set; } = 0; + + /// + /// sign_qty + /// + [Display(Name = "sign_qty")] + public int sign_qty { get; set; } = 0; + + /// + /// package_no + /// + [Display(Name = "package_no")] + [MaxLength(32,ErrorMessage = "MaxLength")] + public string package_no { get; set; } = string.Empty; + + /// + /// package_person + /// + [Display(Name = "package_person")] + [MaxLength(64,ErrorMessage = "MaxLength")] + public string package_person { get; set; } = string.Empty; + + /// + /// package_time + /// + [Display(Name = "package_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime package_time { get; set; } = UtilConvert.MinDate; + + /// + /// weighing_no + /// + [Display(Name = "weighing_no")] + [MaxLength(32,ErrorMessage = "MaxLength")] + public string weighing_no { get; set; } = string.Empty; + + /// + /// weighing_person + /// + [Display(Name = "weighing_person")] + [MaxLength(64,ErrorMessage = "MaxLength")] + public string weighing_person { get; set; } = string.Empty; + + /// + /// weighing_weight + /// + [Display(Name = "weighing_weight")] + public decimal weighing_weight { get; set; } = 0; + + /// + /// waybill_no + /// + [Display(Name = "waybill_no")] + [MaxLength(64,ErrorMessage = "MaxLength")] + public string waybill_no { get; set; } = string.Empty; + + /// + /// carrier + /// + [Display(Name = "carrier")] + [MaxLength(256,ErrorMessage = "MaxLength")] + public string carrier { get; set; } = string.Empty; + + /// + /// freightfee + /// + [Display(Name = "freightfee")] + public decimal freightfee { get; set; } = 0; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// spu_description + /// + public string spu_description { get; set; } = string.Empty; + + /// + /// bar_code + /// + public string bar_code { get; set; } = string.Empty; + + /// + /// volume_unit + /// + public byte volume_unit { get; set; } = 0; + + /// + /// weight_unit + /// + public byte weight_unit { get; set; } = 0; + + /// + /// length_unit + /// + public byte length_unit { get; set; } = 0; + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistWeightViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistWeightViewModel.cs new file mode 100644 index 0000000..777c93c --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistWeightViewModel.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// DispatchlistWeightViewModel + /// + public class DispatchlistWeightViewModel + { + #region constructor + /// + /// constructor + /// + public DispatchlistWeightViewModel() + { + + } + #endregion + #region Property + [Display(Name = "id")] + public int id { get; set; } = 0; + /// + /// dispatch_no + /// + [Display(Name = "dispatch_no")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string dispatch_no { get; set; } = string.Empty; + + /// + /// dispatch_status + /// + [Display(Name = "dispatch_status")] + public byte dispatch_status { get; set; } = 0; + + /// + /// weighing_qty + /// + [Display(Name = "weighing_qty")] + public int weighing_qty { get; set; } = 0; + + /// + /// weighing_weight + /// + [Display(Name = "weighing_weight")] + public decimal weighing_weight { get; set; } = 0; + + /// + /// picked_qty + /// + [Display(Name = "picked_qty")] + public int picked_qty { get; set; } = 0; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchpicklistViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchpicklistViewModel.cs new file mode 100644 index 0000000..c842922 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchpicklistViewModel.cs @@ -0,0 +1,123 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// dispatchpicklist viewModel + /// + public class DispatchpicklistViewModel + { + + #region constructor + /// + /// constructor + /// + public DispatchpicklistViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// dispatchlist_id + /// + [Display(Name = "dispatchlist_id")] + public int dispatchlist_id { get; set; } = 0; + + /// + /// goods_owner_id + /// + [Display(Name = "goods_owner_id")] + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_location_id + /// + [Display(Name = "goods_location_id")] + public int goods_location_id { get; set; } = 0; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// pick_qty + /// + [Display(Name = "pick_qty")] + public int pick_qty { get; set; } = 0; + + /// + /// picked_qty + /// + [Display(Name = "picked_qty")] + public int picked_qty { get; set; } = 0; + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// spu_description + /// + public string spu_description { get; set; } = string.Empty; + + /// + /// bar_code + /// + public string bar_code { get; set; } = string.Empty; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// goods owner name + /// + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// warehouse_name + /// + public string warehouse_name { get; set; } = string.Empty; + + /// + /// warehouse_area_name + /// + public string warehouse_area_name { get; set; } = string.Empty; + + /// + /// warehouse_area_property + /// + public byte warehouse_area_property { get; set; } = 0; + + /// + /// location_name + /// + public string location_name { get; set; } = string.Empty; + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/PreDispatchlistViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/PreDispatchlistViewModel.cs new file mode 100644 index 0000000..4ff80a9 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/PreDispatchlistViewModel.cs @@ -0,0 +1,87 @@ +using ModernWMS.Core.Utility; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// Advance Dispatchlist viewModel + /// + public class PreDispatchlistViewModel + { + #region constructor + /// + /// constructor + /// + public PreDispatchlistViewModel() + { + + } + #endregion + #region Property + /// + /// dispatch_no + /// + [Display(Name = "dispatch_no")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string dispatch_no { get; set; } = string.Empty; + + /// + /// dispatch_status + /// + [Display(Name = "dispatch_status")] + public byte dispatch_status { get; set; } = 0; + + /// + /// customer_id + /// + [Display(Name = "customer_id")] + public int customer_id { get; set; } = 0; + + /// + /// customer_name + /// + [Display(Name = "customer_name")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string customer_name { get; set; } = string.Empty; + + /// + /// qty + /// + [Display(Name = "qty")] + public int qty { get; set; } = 0; + + /// + /// weight + /// + [Display(Name = "weight")] + public decimal weight { get; set; } = 0; + + /// + /// volume + /// + [Display(Name = "volume")] + public decimal volume { get; set; } = 0; + + /// + /// tenant_id + /// + public long tenant_id { get; set; } = 0; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Freightfee/FreightfeeExcelmportViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Freightfee/FreightfeeExcelmportViewModel.cs new file mode 100644 index 0000000..2633aef --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Freightfee/FreightfeeExcelmportViewModel.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + public class FreightfeeExcelmportViewModel + { + #region constructor + /// + /// constructor + /// + public FreightfeeExcelmportViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// carrier + /// + [Display(Name = "carrier")] + [MaxLength(256, ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string carrier { get; set; } = string.Empty; + + /// + /// departure_city + /// + [Display(Name = "departure_city")] + [MaxLength(128, ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string departure_city { get; set; } = string.Empty; + + /// + /// arrival_city + /// + [Display(Name = "arrival_city")] + [MaxLength(128, ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string arrival_city { get; set; } = string.Empty; + + /// + /// price_per_weight + /// + [Display(Name = "price_per_weight")] + [Required(ErrorMessage = "Required")] + public decimal price_per_weight { get; set; } = 0; + + /// + /// price_per_volume + /// + [Display(Name = "price_per_volume")] + [Required(ErrorMessage = "Required")] + public decimal price_per_volume { get; set; } = 0; + + /// + /// min_payment + /// + [Display(Name = "min_payment")] + [Required(ErrorMessage = "Required")] + public decimal min_payment { get; set; } = 0; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Freightfee/FreightfeeViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Freightfee/FreightfeeViewModel.cs new file mode 100644 index 0000000..5f3361d --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Freightfee/FreightfeeViewModel.cs @@ -0,0 +1,116 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// freightfee viewModel + /// + public class FreightfeeViewModel + { + + #region constructor + /// + /// constructor + /// + public FreightfeeViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// carrier + /// + [Display(Name = "carrier")] + [MaxLength(256,ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string carrier { get; set; } = string.Empty; + + /// + /// departure_city + /// + [Display(Name = "departure_city")] + [MaxLength(128,ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string departure_city { get; set; } = string.Empty; + + /// + /// arrival_city + /// + [Display(Name = "arrival_city")] + [MaxLength(128,ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string arrival_city { get; set; } = string.Empty; + + /// + /// price_per_weight + /// + [Display(Name = "price_per_weight")] + [Required(ErrorMessage = "Required")] + public decimal price_per_weight { get; set; } = 0; + + /// + /// price_per_volume + /// + [Display(Name = "price_per_volume")] + [Required(ErrorMessage = "Required")] + public decimal price_per_volume { get; set; } = 0; + + /// + /// min_payment + /// + [Display(Name = "min_payment")] + [Required(ErrorMessage = "Required")] + public decimal min_payment { get; set; } = 0; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64,ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// is_valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } =true; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/GoodsOwner/GoodsownerImportViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/GoodsOwner/GoodsownerImportViewModel.cs new file mode 100644 index 0000000..efd4784 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/GoodsOwner/GoodsownerImportViewModel.cs @@ -0,0 +1,71 @@ +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// goods owner view model + /// + public class GoodsownerImportViewModel + { + #region constructor + /// + /// constructor + /// + public GoodsownerImportViewModel() + { + + } + #endregion + + #region Property + + /// + /// goods owner's name + /// + [Display(Name = "goods_owner_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// city + /// + [Display(Name = "city")] + [Required(ErrorMessage = "Required")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string city { get; set; } = string.Empty; + + /// + /// address + /// + [Display(Name = "address")] + [Required(ErrorMessage = "Required")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string address { get; set; } = string.Empty; + + /// + /// manager + /// + [Display(Name = "manager")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string manager { get; set; } = string.Empty; + + /// + /// contact tel + /// + [Display(Name = "contact_tel")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string contact_tel { get; set; } = string.Empty; + + /// + /// _XID + /// + public string _XID { get; set; } = string.Empty; + + /// + /// error message + /// + public string errorMsg { get; set; } = string.Empty; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/GoodsOwner/GoodsownerViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/GoodsOwner/GoodsownerViewModel.cs new file mode 100644 index 0000000..7c248ae --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/GoodsOwner/GoodsownerViewModel.cs @@ -0,0 +1,91 @@ +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// goods owner view model + /// + public class GoodsownerViewModel + { + #region constructor + /// + /// constructor + /// + public GoodsownerViewModel() + { + + } + #endregion + + #region Property + + /// + /// primary key + /// + public int id { get; set; } = 0; + + /// + /// goods owner's name + /// + [Display(Name = "goods_owner_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// city + /// + [Display(Name = "city")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string city { get; set; } = string.Empty; + + /// + /// address + /// + [Display(Name = "address")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string address { get; set; } = string.Empty; + + /// + /// manager + /// + [Display(Name = "manager")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string manager { get; set; } = string.Empty; + + /// + /// contact tel + /// + [Display(Name = "contact_tel")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string contact_tel { get; set; } = string.Empty; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last update time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = DateTime.Now; + + /// + /// valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } = true; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Goodslocation/GoodslocationViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Goodslocation/GoodslocationViewModel.cs new file mode 100644 index 0000000..0343c59 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Goodslocation/GoodslocationViewModel.cs @@ -0,0 +1,165 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// goodslocation viewModel + /// + public class GoodslocationViewModel + { + + #region constructor + /// + /// constructor + /// + public GoodslocationViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// warehouse_id + /// + [Display(Name = "warehouse_id")] + public int warehouse_id { get; set; } = 0; + + /// + /// warehouse_name + /// + [Display(Name = "warehouse_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(32,ErrorMessage = "MaxLength")] + public string warehouse_name { get; set; } = string.Empty; + + /// + /// warehouse_area_name + /// + [Display(Name = "warehouse_area_name")] + [MaxLength(32,ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string warehouse_area_name { get; set; } = string.Empty; + + /// + /// warehouse_area_property + /// + [Display(Name = "warehouse_area_property")] + [Required(ErrorMessage = "Required")] + public byte warehouse_area_property { get; set; } = 0; + + /// + /// location_name + /// + [Display(Name = "location_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(64,ErrorMessage = "MaxLength")] + public string location_name { get; set; } = string.Empty; + + /// + /// location_length + /// + [Display(Name = "location_length")] + public decimal location_length { get; set; } = 0; + + /// + /// location_width + /// + [Display(Name = "location_width")] + public decimal location_width { get; set; } = 0; + + /// + /// location_heigth + /// + [Display(Name = "location_heigth")] + public decimal location_heigth { get; set; } = 0; + + /// + /// location_volume + /// + [Display(Name = "location_volume")] + public decimal location_volume { get; set; } = 0; + + /// + /// location_load + /// + [Display(Name = "location_load")] + public decimal location_load { get; set; } = 0; + + /// + /// roadway_number + /// + [Display(Name = "roadway_number")] + [MaxLength(10,ErrorMessage = "MaxLength")] + public string roadway_number { get; set; } = string.Empty; + + /// + /// shelf_number + /// + [Display(Name = "shelf_number")] + [MaxLength(10,ErrorMessage = "MaxLength")] + public string shelf_number { get; set; } = string.Empty; + + /// + /// layer_number + /// + [Display(Name = "layer_number")] + [MaxLength(10,ErrorMessage = "MaxLength")] + public string layer_number { get; set; } = string.Empty; + + /// + /// tag_number + /// + [Display(Name = "tag_number")] + [MaxLength(10,ErrorMessage = "MaxLength")] + public string tag_number { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// is_valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } =true; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + /// + /// warehouse_area_id + /// + [Display(Name = "warehouse_area_id")] + public int warehouse_area_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/MenuViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/MenuViewModel.cs new file mode 100644 index 0000000..f553021 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/MenuViewModel.cs @@ -0,0 +1,51 @@ +/* + * date:2022-12-20 + * developer:AMo + */ +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// menu viewModel + /// + public class MenuViewModel + { + + /// + /// id + /// + public int id { get; set; } = 0; + + /// + /// menu_name + /// + public string menu_name { get; set; } = string.Empty; + + /// + /// module + /// + public string module { get; set; } = string.Empty; + + /// + /// vue_path + /// + public string vue_path { get; set; } = string.Empty; + + /// + /// vue_path_detail + /// + public string vue_path_detail { get; set; } = string.Empty; + + /// + /// vue_directory + /// + public string vue_directory { get; set; } = string.Empty; + + /// + /// sort + /// + public int sort { get; set; } = 0; + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/RolemenuBothViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/RolemenuBothViewModel.cs new file mode 100644 index 0000000..ac7ff83 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/RolemenuBothViewModel.cs @@ -0,0 +1,51 @@ +/* + * date:2022-12-20 + * developer:AMo + */ +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// rolemenu viewModel + /// + public class RolemenuBothViewModel + { + #region constructor + /// + /// constructor + /// + public RolemenuBothViewModel() + { + + } + #endregion + + #region Property + + /// + /// userrole_id + /// + [Display(Name = "userrole_id")] + [Required(ErrorMessage = "Required")] + public int userrole_id { get; set; } = 0; + + /// + /// role_name + /// + [Display(Name = "role_name")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string role_name { get; set; } = string.Empty; + + /// + /// role valid + /// + public bool is_valid { get; set; } = true; + + /// + /// menu details + /// + public List detailList { get; set; } = new List(); + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/RolemenuListViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/RolemenuListViewModel.cs new file mode 100644 index 0000000..bc4e57e --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/RolemenuListViewModel.cs @@ -0,0 +1,56 @@ +/* + * date:2022-12-20 + * developer:AMo + */ +using ModernWMS.Core.Utility; +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// rolemenu list viewModel + /// + public class RolemenuListViewModel + { + #region constructor + /// + /// constructor + /// + public RolemenuListViewModel() + { + + } + #endregion + + #region Property + + /// + /// userrole_id + /// + public int userrole_id { get; set; } = 0; + + /// + /// role_name + /// + public string role_name { get; set; } = string.Empty; + + + /// + /// role valid + /// + public bool is_valid { get; set; } = true; + + + /// + /// create_time + /// + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/RolemenuViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/RolemenuViewModel.cs new file mode 100644 index 0000000..39ea08b --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Rolemenu/RolemenuViewModel.cs @@ -0,0 +1,55 @@ +/* + * date:2022-12-20 + * developer:AMo + */ +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// rolemenu viewModel + /// + public class RolemenuViewModel + { + + #region constructor + /// + /// constructor + /// + public RolemenuViewModel() + { + + } + #endregion + + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// menu_id + /// + [Display(Name = "menu_id")] + public int menu_id { get; set; } = 0; + + /// + /// menu_name + /// + [Display(Name = "menu_name")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string menu_name { get; set; } = string.Empty; + + /// + /// authority + /// + [Display(Name = "authority")] + public byte authority { get; set; } = 1; + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Sku/CategoryViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Sku/CategoryViewModel.cs new file mode 100644 index 0000000..bd11a30 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Sku/CategoryViewModel.cs @@ -0,0 +1,77 @@ +/* + * date:2022-12-20 + * developer:AMo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// category viewModel + /// + public class CategoryViewModel + { + + #region constructor + /// + /// constructor + /// + public CategoryViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// category_name + /// + [Display(Name = "category_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string category_name { get; set; } = string.Empty; + + /// + /// parent_id + /// + [Display(Name = "parent_id")] + public int parent_id { get; set; } = 0; + + /// + /// creator + /// + [Display(Name = "creator")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// is_valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } = true; + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SkuDetailViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SkuDetailViewModel.cs new file mode 100644 index 0000000..4a396dd --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SkuDetailViewModel.cs @@ -0,0 +1,195 @@ +/* + * date:2-23-01-05 + * developer:NoNo + */ + +using System.ComponentModel.DataAnnotations; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// spu with sku viewModel + /// + public class SkuDetailViewModel + { + #region constructor + /// + /// constructor + /// + public SkuDetailViewModel() + { + + } + #endregion + + #region Property + + /// + /// spu_id + /// + [Display(Name = "spu_id")] + public int spu_id { get; set; } = 0; + + /// + /// spu_code + /// + [Display(Name = "spu_code")] + [Required(ErrorMessage = "Required")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + [Display(Name = "spu_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(200, ErrorMessage = "MaxLength")] + public string spu_name { get; set; } = string.Empty; + + /// + /// category_id + /// + [Display(Name = "category_id")] + public int category_id { get; set; } = 0; + + /// + /// category_name + /// + [Display(Name = "category_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string category_name { get; set; } = string.Empty; + + /// + /// spu_description + /// + [Display(Name = "spu_description")] + [MaxLength(1000, ErrorMessage = "MaxLength")] + public string spu_description { get; set; } = string.Empty; + + /// + /// bar_code + /// + [Display(Name = "bar_code")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string bar_code { get; set; } = string.Empty; + + /// + /// supplier_id + /// + [Display(Name = "supplier_id")] + public int supplier_id { get; set; } = 0; + + /// + /// supplier_name + /// + [Display(Name = "supplier_name")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string supplier_name { get; set; } = string.Empty; + + /// + /// brand + /// + [Display(Name = "brand")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string brand { get; set; } = string.Empty; + + /// + /// origin + /// + [Display(Name = "origin")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string origin { get; set; } = string.Empty; + + /// + /// length_unit (0=毫米、1=厘米、2=分米、3=米) + /// + [Display(Name = "length_unit")] + public byte length_unit { get; set; } = 0; + + /// + /// volume_unit (0=立方厘米、1=立方分米、2=立方米) + /// + [Display(Name = "volume_unit")] + public byte volume_unit { get; set; } = 0; + + /// + /// weight_unit (0=毫克、1=克、2=千克) + /// + [Display(Name = "weight_unit")] + public byte weight_unit { get; set; } = 0; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// sku_code + /// + [Display(Name = "sku_code")] + [Required(ErrorMessage = "Required")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string sku_code { get; set; } = string.Empty; + + /// + /// sku_name + /// + [Display(Name = "sku_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(200, ErrorMessage = "MaxLength")] + public string sku_name { get; set; } = string.Empty; + + /// + /// weight + /// + [Display(Name = "weight")] + public decimal weight { get; set; } = 0; + + /// + /// lenght + /// + [Display(Name = "lenght")] + public decimal lenght { get; set; } = 0; + + /// + /// width + /// + [Display(Name = "width")] + public decimal width { get; set; } = 0; + + /// + /// height + /// + [Display(Name = "height")] + public decimal height { get; set; } = 0; + + /// + /// volume + /// + [Display(Name = "volume")] + public decimal volume { get; set; } = 0; + + /// + /// unit + /// + [Display(Name = "unit")] + [MaxLength(5, ErrorMessage = "MaxLength")] + public string unit { get; set; } = string.Empty; + + /// + /// cost + /// + [Display(Name = "cost")] + public decimal cost { get; set; } = 0; + + /// + /// price + /// + [Display(Name = "price")] + public decimal price { get; set; } = 0; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SkuSelectViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SkuSelectViewModel.cs new file mode 100644 index 0000000..3899115 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SkuSelectViewModel.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + public class SkuSelectViewModel + { + public SkuSelectViewModel() + { + + } + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// spu_id + /// + public int spu_id { get; set; } = 0; + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// sku_name + /// + public string sku_name { get; set; } = string.Empty; + + + /// + /// supplier_id + /// + public int supplier_id { get; set; } = 0; + + /// + /// supplier_name + /// + public string supplier_name { get; set; } = string.Empty; + + /// + /// brand + /// + public string brand { get; set; } = string.Empty; + + /// + /// origin + /// + public string origin { get; set; } = string.Empty; + + /// + /// unit + /// + public string unit { get; set; } = string.Empty; + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SkuViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SkuViewModel.cs new file mode 100644 index 0000000..cdb1980 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SkuViewModel.cs @@ -0,0 +1,122 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// sku viewModel + /// + public class SkuViewModel + { + + #region constructor + /// + /// constructor + /// + public SkuViewModel() + { + + } + #endregion + + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// spu_id + /// + [Display(Name = "spu_id")] + public int spu_id { get; set; } = 0; + + /// + /// sku_code + /// + [Display(Name = "sku_code")] + [Required(ErrorMessage = "Required")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string sku_code { get; set; } = string.Empty; + + /// + /// sku_name + /// + [Display(Name = "sku_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(200, ErrorMessage = "MaxLength")] + public string sku_name { get; set; } = string.Empty; + + /// + /// weight + /// + [Display(Name = "weight")] + public decimal weight { get; set; } = 0; + + /// + /// lenght + /// + [Display(Name = "lenght")] + public decimal lenght { get; set; } = 0; + + /// + /// width + /// + [Display(Name = "width")] + public decimal width { get; set; } = 0; + + /// + /// height + /// + [Display(Name = "height")] + public decimal height { get; set; } = 0; + + /// + /// volume + /// + [Display(Name = "volume")] + public decimal volume { get; set; } = 0; + + /// + /// unit + /// + [Display(Name = "unit")] + [MaxLength(5, ErrorMessage = "MaxLength")] + public string unit { get; set; } = string.Empty; + + /// + /// cost + /// + [Display(Name = "cost")] + public decimal cost { get; set; } = 0; + + /// + /// price + /// + [Display(Name = "price")] + public decimal price { get; set; } = 0; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = DateTime.Now; + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SpuBothViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SpuBothViewModel.cs new file mode 100644 index 0000000..afe0df1 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SpuBothViewModel.cs @@ -0,0 +1,30 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// spu with sku viewModel + /// + public class SpuBothViewModel : SpuViewModel + { + #region constructor + /// + /// constructor + /// + public SpuBothViewModel() + { + + } + #endregion + + #region details + /// + /// sku + /// + public List detailList { get; set; } = new List(); + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SpuViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SpuViewModel.cs new file mode 100644 index 0000000..6c820ca --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Sku/SpuViewModel.cs @@ -0,0 +1,153 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// spu viewModel + /// + public class SpuViewModel + { + + #region constructor + /// + /// constructor + /// + public SpuViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// spu_code + /// + [Display(Name = "spu_code")] + [Required(ErrorMessage = "Required")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + [Display(Name = "spu_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(200, ErrorMessage = "MaxLength")] + public string spu_name { get; set; } = string.Empty; + + /// + /// category_id + /// + [Display(Name = "category_id")] + public int category_id { get; set; } = 0; + + /// + /// category_name + /// + [Display(Name = "category_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string category_name { get; set; } = string.Empty; + + /// + /// spu_description + /// + [Display(Name = "spu_description")] + [MaxLength(1000, ErrorMessage = "MaxLength")] + public string spu_description { get; set; } = string.Empty; + + /// + /// bar_code + /// + [Display(Name = "bar_code")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string bar_code { get; set; } = string.Empty; + + /// + /// supplier_id + /// + [Display(Name = "supplier_id")] + public int supplier_id { get; set; } = 0; + + /// + /// supplier_name + /// + [Display(Name = "supplier_name")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string supplier_name { get; set; } = string.Empty; + + /// + /// brand + /// + [Display(Name = "brand")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string brand { get; set; } = string.Empty; + + /// + /// origin + /// + [Display(Name = "origin")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string origin { get; set; } = string.Empty; + + /// + /// length_unit (0=毫米、1=厘米、2=分米、3=米) + /// + [Display(Name = "length_unit")] + public byte length_unit { get; set; } = 0; + + /// + /// volume_unit (0=立方厘米、1=立方分米、2=立方米) + /// + [Display(Name = "volume_unit")] + public byte volume_unit { get; set; } = 0; + + /// + /// weight_unit (0=毫克、1=克、2=千克) + /// + [Display(Name = "weight_unit")] + public byte weight_unit { get; set; } = 0; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = DateTime.Now; + + /// + /// is_valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } = true; + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stock/LocationStockManagementViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stock/LocationStockManagementViewModel.cs new file mode 100644 index 0000000..343148b --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stock/LocationStockManagementViewModel.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// goods location stock management viewmodel + /// + public class LocationStockManagementViewModel + { + /// + /// warehouse_name + /// + public string warehouse_name { get; set; } = string.Empty; + + /// + /// location_name + /// + public string location_name { get; set; } = string.Empty; + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// sku_name + /// + public string sku_name { get; set; } = string.Empty; + + /// + /// quantity + /// + public int qty { get; set; } = 0; + + /// + /// quantity available + /// + public int qty_available { get; set; } = 0; + + /// + /// quantity locked + /// + public int qty_locked { get; set; } = 0; + + /// + /// quantity frozen + /// + public int qty_frozen { get; set; } = 0; + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stock/StockManagementViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stock/StockManagementViewModel.cs new file mode 100644 index 0000000..93ecbd7 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stock/StockManagementViewModel.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// StockManagementViewModel + /// + public class StockManagementViewModel + { + #region constructor + /// + /// constructor + /// + public StockManagementViewModel() + { + + } + #endregion + #region Property + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// quantity + /// + public int qty { get; set; } = 0; + + /// + /// quantity available + /// + public int qty_available { get; set; } = 0; + + /// + /// quantity locked + /// + public int qty_locked { get; set; } = 0; + + /// + /// quantity frozen + /// + public int qty_frozen { get; set; } = 0; + + /// + /// asn qty + /// + public int qty_asn { get; set; } = 0; + + /// + /// qty to be unloaded + /// + public int qty_to_unload { get; set; } = 0; + + /// + /// qty to be sorted + /// + public int qty_to_sort { get; set; } = 0; + + /// + /// qty sorted + /// + public int qty_sorted { get; set; } = 0; + + /// + /// shortage qty + /// + public int shortage_qty { get; set; } = 0; + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stock/StockViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stock/StockViewModel.cs new file mode 100644 index 0000000..5aceca8 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stock/StockViewModel.cs @@ -0,0 +1,125 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// stock viewModel + /// + public class StockViewModel + { + + #region constructor + /// + /// constructor + /// + public StockViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// goods_location_id + /// + [Display(Name = "goods_location_id")] + public int goods_location_id { get; set; } = 0; + + /// + /// qty + /// + [Display(Name = "qty")] + public int qty { get; set; } = 0; + + /// + /// goods_owner_id + /// + [Display(Name = "goods_owner_id")] + public int goods_owner_id { get; set; } = 0; + + /// + /// is_freeze + /// + [Display(Name = "is_freeze")] + public bool is_freeze { get; set; } = true; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + /// + /// warehouse_name + /// + public string warehouse_name { get; set; } = string.Empty; + + /// + /// location_name + /// + public string location_name { get; set; } = string.Empty; + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// sku_name + /// + public string sku_name { get; set; } = string.Empty; + + /// + /// unit + /// + public string unit { get; set; } = string.Empty; + + /// + /// qty_available + /// + [Display(Name = "qty_available")] + public int qty_available { get; set; } = 0; + + /// + /// goods owner name + /// + public string goods_owner_name { get; set; } = string.Empty; + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stockadjust/StockadjustViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stockadjust/StockadjustViewModel.cs new file mode 100644 index 0000000..c8e076c --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stockadjust/StockadjustViewModel.cs @@ -0,0 +1,149 @@ +/* + * date:2022-12-26 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// stockadjust viewModel + /// + public class StockadjustViewModel + { + + #region constructor + /// + /// constructor + /// + public StockadjustViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// job_type + /// + [Display(Name = "job_type")] + public byte job_type { get; set; } = 0; + + /// + /// job_code + /// + [Display(Name = "job_code")] + [MaxLength(32,ErrorMessage = "MaxLength")] + public string job_code { get; set; } = string.Empty; + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// sku_name + /// + public string sku_name { get; set; } = string.Empty; + + /// + /// goods_owner_id + /// + [Display(Name = "goods_owner_id")] + public int goods_owner_id { get; set; } = 0; + + /// + /// goods owner's name + /// + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// goods_location_id + /// + [Display(Name = "goods_location_id")] + public int goods_location_id { get; set; } = 0; + + /// + /// warehouse_name + /// + public string warehouse_name { get; set; } = string.Empty; + + /// + /// location_name + /// + public string location_name { get; set; } = string.Empty; + + /// + /// qty + /// + [Display(Name = "qty")] + public int qty { get; set; } = 0; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64,ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + /// + /// is_update_stock + /// + [Display(Name = "is_update_stock")] + public bool is_update_stock { get; set; } =false; + + /// + /// source_table_id + /// + [Display(Name = "source_table_id")] + public int source_table_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stockfreeze/StockfreezeViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stockfreeze/StockfreezeViewModel.cs new file mode 100644 index 0000000..4de60e5 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stockfreeze/StockfreezeViewModel.cs @@ -0,0 +1,119 @@ +/* + * date:2022-12-26 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// stockfreeze viewModel + /// + public class StockfreezeViewModel + { + + #region constructor + /// + /// constructor + /// + public StockfreezeViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// job_code + /// + [Display(Name = "job_code")] + [MaxLength(32,ErrorMessage = "MaxLength")] + public string job_code { get; set; } = string.Empty; + + /// + /// job_type + /// + [Display(Name = "job_type")] + public bool job_type { get; set; } =true; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// goods_owner_id + /// + [Display(Name = "goods_owner_id")] + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_location_id + /// + [Display(Name = "goods_location_id")] + public int goods_location_id { get; set; } = 0; + + /// + /// operator + /// + [Display(Name = "handler")] + [MaxLength(64,ErrorMessage = "MaxLength")] + public string handler { get; set; } = string.Empty; + + /// + /// operate_time + /// + [Display(Name = "handle_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime handle_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + /// + /// warehouse_name + /// + public string warehouse_name { get; set; } = string.Empty; + + /// + /// location_name + /// + public string location_name { get; set; } = string.Empty; + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stockmove/StockmoveViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stockmove/StockmoveViewModel.cs new file mode 100644 index 0000000..a336461 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stockmove/StockmoveViewModel.cs @@ -0,0 +1,160 @@ +/* + * date:2022-12-27 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// stockmove viewModel + /// + public class StockmoveViewModel + { + + #region constructor + /// + /// constructor + /// + public StockmoveViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// job_code + /// + [Display(Name = "job_code")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string job_code { get; set; } = string.Empty; + + /// + /// move_status + /// + [Display(Name = "move_status")] + public byte move_status { get; set; } = 0; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// orig_goods_location_id + /// + [Display(Name = "orig_goods_location_id")] + public int orig_goods_location_id { get; set; } = 0; + + /// + /// dest_googs_location_id + /// + [Display(Name = "dest_googs_location_id")] + public int dest_googs_location_id { get; set; } = 0; + + /// + /// qty + /// + [Display(Name = "qty")] + public int qty { get; set; } = 0; + + /// + /// goods_owner_id + /// + [Display(Name = "goods_owner_id")] + public int goods_owner_id { get; set; } = 0; + + /// + /// handler + /// + [Display(Name = "handler")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string handler { get; set; } = string.Empty; + + /// + /// handle_time + /// + [Display(Name = "handle_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime handle_time { get; set; } = UtilConvert.MinDate; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + /// + /// origin warehouse + /// + public string orig_goods_warehouse { get; set; } = string.Empty; + + /// + /// origin location_name + /// + public string orig_goods_location_name { get; set; } = string.Empty; + + /// + /// destination warehouse + /// + public string dest_googs_warehouse { get; set; } = string.Empty; + + /// + /// destination location_name + /// + public string dest_googs_location_name { get; set; } = string.Empty; + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// sku_name + /// + public string sku_name { get; set; } = string.Empty; + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessGetViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessGetViewModel.cs new file mode 100644 index 0000000..fc1a6be --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessGetViewModel.cs @@ -0,0 +1,103 @@ +/* + * date:2022-12-23 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// stockprocess viewModel without details + /// + public class StockprocessGetViewModel + { + + #region constructor + /// + /// constructor + /// + public StockprocessGetViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// job_code + /// + [Display(Name = "job_code")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string job_code { get; set; } = string.Empty; + + /// + /// job_type + /// + [Display(Name = "job_type")] + public bool job_type { get; set; } = true; + + /// + /// process_status + /// + [Display(Name = "process_status")] + public bool process_status { get; set; } = true; + + /// + /// processor + /// + [Display(Name = "processor")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string processor { get; set; } = string.Empty; + + /// + /// process_time + /// + [Display(Name = "process_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime process_time { get; set; } = UtilConvert.MinDate; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + /// + /// adjust_status + /// + public bool adjust_status { get; set; } = true; + #endregion + + + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessViewModel.cs new file mode 100644 index 0000000..4c83e15 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessViewModel.cs @@ -0,0 +1,106 @@ +/* + * date:2022-12-23 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// stockprocess viewModel + /// + public class StockprocessViewModel + { + + #region constructor + /// + /// constructor + /// + public StockprocessViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// job_code + /// + [Display(Name = "job_code")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string job_code { get; set; } = string.Empty; + + /// + /// job_type + /// + [Display(Name = "job_type")] + public bool job_type { get; set; } = true; + + /// + /// process_status + /// + [Display(Name = "process_status")] + public bool process_status { get; set; } = true; + + /// + /// processor + /// + [Display(Name = "processor")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string processor { get; set; } = string.Empty; + + /// + /// process_time + /// + [Display(Name = "process_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime process_time { get; set; } = UtilConvert.MinDate; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + + #endregion + + #region detail table + + /// + /// detail table + /// + public List detailList { get; set; } = new List(2); + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessWithDetailViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessWithDetailViewModel.cs new file mode 100644 index 0000000..d890c9f --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessWithDetailViewModel.cs @@ -0,0 +1,109 @@ +using ModernWMS.Core.Utility; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// get Stockprocess with + /// + public class StockprocessWithDetailViewModel + { + + #region constructor + /// + /// constructor + /// + public StockprocessWithDetailViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// job_code + /// + [Display(Name = "job_code")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string job_code { get; set; } = string.Empty; + + /// + /// job_type + /// + [Display(Name = "job_type")] + public bool job_type { get; set; } = true; + + /// + /// process_status + /// + [Display(Name = "process_status")] + public bool process_status { get; set; } = true; + + /// + /// processor + /// + [Display(Name = "processor")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string processor { get; set; } = string.Empty; + + /// + /// process_time + /// + [Display(Name = "process_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime process_time { get; set; } = UtilConvert.MinDate; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + /// + /// adjust_status + /// + public bool adjust_status { get; set; } = true; + + #endregion + /// + /// source detail table + /// + public List source_detail_list { get; set; } = new List(2); + /// + /// target detail table + /// + public List target_detail_list { get; set; } = new List(2); + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessdetailViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessdetailViewModel.cs new file mode 100644 index 0000000..7c8f44d --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessdetailViewModel.cs @@ -0,0 +1,115 @@ +/* + * date:2022-12-23 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// stockprocessdetail viewModel + /// + public class StockprocessdetailViewModel + { + + #region constructor + /// + /// constructor + /// + public StockprocessdetailViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// stock_process_id + /// + [Display(Name = "stock_process_id")] + public int stock_process_id { get; set; } = 0; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// goods_owner_id + /// + [Display(Name = "goods_owner_id")] + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_location_id + /// + [Display(Name = "goods_location_id")] + public int goods_location_id { get; set; } = 0; + + /// + /// qty + /// + [Display(Name = "qty")] + public int qty { get; set; } = 0; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + /// + /// is_source + /// + [Display(Name = "is_source")] + public bool is_source { get; set; } = true; + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// unit + /// + public string unit { get; set; } = string.Empty; + + /// + /// is_update_stock + /// + public bool is_update_stock { get; set; } = false; + + /// + /// goods location name + /// + public string location_name { get; set; } = string.Empty; + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stocktaking/StocktakingBasicViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stocktaking/StocktakingBasicViewModel.cs new file mode 100644 index 0000000..6c33d58 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stocktaking/StocktakingBasicViewModel.cs @@ -0,0 +1,88 @@ +/* + * date:2022-12-30 + * developer:AMo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// stocktaking basic viewModel + /// + public class StocktakingBasicViewModel + { + #region constructor + /// + /// constructor + /// + public StocktakingBasicViewModel() + { + + } + #endregion + #region Property + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// sku_name + /// + public string sku_name { get; set; } = string.Empty; + + /// + /// goods_owner_id + /// + [Display(Name = "goods_owner_id")] + public int goods_owner_id { get; set; } = 0; + + /// + /// goods owner's name + /// + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// goods_location_id + /// + [Display(Name = "goods_location_id")] + public int goods_location_id { get; set; } = 0; + + /// + /// warehouse_name + /// + public string warehouse_name { get; set; } = string.Empty; + + /// + /// location_name + /// + public string location_name { get; set; } = string.Empty; + + /// + /// book_qty + /// + [Display(Name = "book_qty")] + public int book_qty { get; set; } = 0; + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stocktaking/StocktakingConfirmViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stocktaking/StocktakingConfirmViewModel.cs new file mode 100644 index 0000000..d1a80a8 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stocktaking/StocktakingConfirmViewModel.cs @@ -0,0 +1,42 @@ +/* + * date:2022-12-30 + * developer:AMo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// stocktaking confirm counted_qty viewModel + /// + public class StocktakingConfirmViewModel + { + #region constructor + /// + /// constructor + /// + public StocktakingConfirmViewModel() + { + + } + #endregion + + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// counted_qty + /// + [Display(Name = "counted_qty")] + public int counted_qty { get; set; } = 0; + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stocktaking/StocktakingViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stocktaking/StocktakingViewModel.cs new file mode 100644 index 0000000..2e9f7e5 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stocktaking/StocktakingViewModel.cs @@ -0,0 +1,99 @@ +/* + * date:2022-12-30 + * developer:AMo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// stocktaking viewModel + /// + public class StocktakingViewModel : StocktakingBasicViewModel + { + + #region constructor + /// + /// constructor + /// + public StocktakingViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// job_code + /// + [Display(Name = "job_code")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string job_code { get; set; } = string.Empty; + + /// + /// job_status + /// + [Display(Name = "job_status")] + public bool job_status { get; set; } = false; + + /// + /// adjust_status + /// + public bool adjust_status { get; set; } = false; + + /// + /// counted_qty + /// + [Display(Name = "counted_qty")] + public int counted_qty { get; set; } = 0; + + /// + /// difference_qty + /// + [Display(Name = "difference_qty")] + public int difference_qty { get; set; } = 0; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// handler + /// + [Display(Name = "handler")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string handler { get; set; } = string.Empty; + + /// + /// handle_time + /// + [Display(Name = "handle_time")] + public DateTime handle_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/User/RegisterViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/User/RegisterViewModel.cs new file mode 100644 index 0000000..c89cf2b --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/User/RegisterViewModel.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + public class RegisterViewModel + { + public RegisterViewModel() + { + + } + /// + /// user's name + /// + [Display(Name = "user_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string user_name { get; set; } = string.Empty; + + /// + /// sex + /// + public string sex { get; set; } = string.Empty; + + /// + /// password + /// + [Display(Name = "password")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string auth_string { get; set; } = string.Empty; + + /// + /// email + /// + [Display(Name = "email")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string email { get; set; } = string.Empty; + + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/User/UserChangePwdViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/User/UserChangePwdViewModel.cs new file mode 100644 index 0000000..ff44bd3 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/User/UserChangePwdViewModel.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// what user input when changing password + /// + public class UserChangePwdViewModel + { + /// + /// user's id + /// + public int id { get; set; } = 0; + + /// + /// old password + /// + [Required(ErrorMessage = "Required")] + [Display(Name = "old password")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string old_password { get; set; } = string.Empty; + + /// + /// new password + /// + [Required(ErrorMessage = "Required")] + [Display(Name = "new password")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string new_password { get; set; } = string.Empty; + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/User/UserExcelImportViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/User/UserExcelImportViewModel.cs new file mode 100644 index 0000000..78d339d --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/User/UserExcelImportViewModel.cs @@ -0,0 +1,74 @@ +/* + * date:2022-12-20 + * developer:NoNo + */ +using ModernWMS.Core.Utility; +using System; +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// user import by excel cols viewmodel + /// + public class UserExcelImportViewModel + { + /// + /// user's number + /// + [Display(Name = "user_num")] + [Required(ErrorMessage = "Required")] + [MaxLength(128, ErrorMessage = "MaxLength")] + + public string user_num { get; set; } = string.Empty; + + /// + /// user's name + /// + [Display(Name = "user_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string user_name { get; set; } = string.Empty; + + /// + /// contact + /// + [Display(Name = "contact_tel")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string contact_tel { get; set; } = string.Empty; + + /// + /// user's role + /// + [Display(Name = "user_role")] + [Required(ErrorMessage = "Required")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string user_role { get; set; } = string.Empty; + + /// + /// sex + /// + [Display(Name = "sex")] + [MaxLength(10, ErrorMessage = "MaxLength")] + public string sex { get; set; } = string.Empty; + + /// + /// is_valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } = false; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// tenant + /// + [Display(Name = "tenant")] + public long tenant_id { get; set; } = 0; + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/User/UserViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/User/UserViewModel.cs new file mode 100644 index 0000000..6aca893 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/User/UserViewModel.cs @@ -0,0 +1,107 @@ +using ModernWMS.Core.Utility; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + public class UserViewModel + { + #region constructor + public UserViewModel() + { + + } + #endregion + #region property + + /// + /// primary key + /// + public int id { get; set; } = 0; + + /// + /// user's number + /// + [Display(Name ="user_num")] + [Required(ErrorMessage = "Required")] + [MaxLength(128, ErrorMessage = "MaxLength")] + + public string user_num { get; set; } = string.Empty; + + /// + /// user's name + /// + [Display(Name = "user_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string user_name { get; set; } = string.Empty; + + /// + /// contact + /// + [Display(Name = "contact_tel")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string contact_tel { get; set; } = string.Empty; + + /// + /// user's role + /// + [Display(Name = "user_role")] + [Required(ErrorMessage = "Required")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string user_role { get; set; } = string.Empty; + + /// + /// sex + /// + [Display(Name = "sex")] + [MaxLength(10, ErrorMessage = "MaxLength")] + public string sex { get; set; } = string.Empty; + + /// + /// is_valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } = false; + + /// + /// password + /// + [Display(Name = "password")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string auth_string { get; set; } = string.Empty; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// createtime + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last update time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant + /// + [Display(Name = "tenant")] + public long tenant_id { get; set; } = 0; + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Warehouse/WarehouseExcelImportViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Warehouse/WarehouseExcelImportViewModel.cs new file mode 100644 index 0000000..813e1c5 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Warehouse/WarehouseExcelImportViewModel.cs @@ -0,0 +1,76 @@ +using ModernWMS.Core.Utility; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + public class WarehouseExcelImportViewModel + { + #region constructor + /// + /// constructor + /// + public WarehouseExcelImportViewModel() + { + + } + #endregion + #region Property + + + /// + /// warehouse_name + /// + [Display(Name = "warehouse_name")] + [MaxLength(32, ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string warehouse_name { get; set; } = string.Empty; + + /// + /// city + /// + [Display(Name = "city")] + [MaxLength(128, ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string city { get; set; } = string.Empty; + + /// + /// address + /// + [Display(Name = "address")] + [MaxLength(256, ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string address { get; set; } = string.Empty; + + /// + /// email + /// + [Display(Name = "email")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string email { get; set; } = string.Empty; + + /// + /// manager + /// + [Display(Name = "manager")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string manager { get; set; } = string.Empty; + + /// + /// contact_tel + /// + [Display(Name = "contact_tel")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string contact_tel { get; set; } = string.Empty; + + + + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Warehouse/WarehouseViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Warehouse/WarehouseViewModel.cs new file mode 100644 index 0000000..a504f0b --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Warehouse/WarehouseViewModel.cs @@ -0,0 +1,116 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// warehouse viewModel + /// + public class WarehouseViewModel + { + + #region constructor + /// + /// constructor + /// + public WarehouseViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// warehouse_name + /// + [Display(Name = "warehouse_name")] + [MaxLength(32, ErrorMessage = "MaxLength")] + [Required(ErrorMessage ="Required")] + public string warehouse_name { get; set; } = string.Empty; + + /// + /// city + /// + [Display(Name = "city")] + [MaxLength(128, ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string city { get; set; } = string.Empty; + + /// + /// address + /// + [Display(Name = "address")] + [MaxLength(256, ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string address { get; set; } = string.Empty; + + /// + /// email + /// + [Display(Name = "email")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string email { get; set; } = string.Empty; + + /// + /// manager + /// + [Display(Name = "manager")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string manager { get; set; } = string.Empty; + + /// + /// contact_tel + /// + [Display(Name = "contact_tel")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string contact_tel { get; set; } = string.Empty; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// is_valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } = true; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Warehousearea/WarehouseareaViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Warehousearea/WarehouseareaViewModel.cs new file mode 100644 index 0000000..ba48ab7 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Warehousearea/WarehouseareaViewModel.cs @@ -0,0 +1,99 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// warehousearea viewModel + /// + public class WarehouseareaViewModel + { + + #region constructor + /// + /// constructor + /// + public WarehouseareaViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// warehouse_id + /// + [Display(Name = "warehouse_id")] + public int warehouse_id { get; set; } = 0; + + + /// + /// warehouse_name + /// + [Display(Name = "warehouse_name")] + [MaxLength(32, ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string warehouse_name { get; set; } = string.Empty; + + /// + /// area_name + /// + [Display(Name = "area_name")] + [MaxLength(32, ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string area_name { get; set; } = string.Empty; + + /// + /// parent_id + /// + [Display(Name = "parent_id")] + public int parent_id { get; set; } = 0; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// is_valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } = true; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + /// + /// area_property + /// + [Display(Name = "area_property")] + public byte area_property { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/company/CompanyViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/company/CompanyViewModel.cs new file mode 100644 index 0000000..2b1b660 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/company/CompanyViewModel.cs @@ -0,0 +1,80 @@ +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// Company + /// + public class CompanyViewModel + { + #region constructor + /// + /// constructor + /// + public CompanyViewModel() + { + + } + #endregion + + #region Property + + /// + /// primary key + /// + public int id { get; set; } = 0; + + /// + /// company's Name + /// + [Display(Name = "company_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(256,ErrorMessage = "MaxLength")] + public string company_name { get; set; } = string.Empty; + + /// + /// city + /// + [Display(Name = "city")] + [Required(ErrorMessage = "Required")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string city { get; set; } = string.Empty; + + /// + /// address + /// + [Display(Name = "address")] + [Required(ErrorMessage = "Required")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string address { get; set; } = string.Empty; + + /// + /// manager + /// + [Display(Name = "manager")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string manager { get; set; } = string.Empty; + + /// + /// contact tel + /// + [Display(Name = "contact_tel")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string contact_tel { get; set; } = string.Empty; + + /// + /// create time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = DateTime.Now; + + /// + /// last update time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = DateTime.Now; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/supplier/SupplierExcelImportViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/supplier/SupplierExcelImportViewModel.cs new file mode 100644 index 0000000..7af1dfd --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/supplier/SupplierExcelImportViewModel.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + public class SupplierExcelImportViewModel + { + + #region constructor + /// + /// constructor + /// + public SupplierExcelImportViewModel() + { + + } + #endregion + #region Property + + /// + /// supplier_name + /// + [Display(Name = "supplier_name")] + [MaxLength(256, ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string supplier_name { get; set; } = string.Empty; + + /// + /// city + /// + [Display(Name = "city")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string city { get; set; } = string.Empty; + + /// + /// address + /// + [Display(Name = "address")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string address { get; set; } = string.Empty; + + /// + /// email + /// + [Display(Name = "email")] + [MaxLength(128, ErrorMessage = "MaxLength")] + public string email { get; set; } = string.Empty; + + /// + /// manager + /// + [Display(Name = "manager")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string manager { get; set; } = string.Empty; + + /// + /// contact_tel + /// + [Display(Name = "contact_tel")] + [MaxLength(64, ErrorMessage = "MaxLength")] + public string contact_tel { get; set; } = string.Empty; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/supplier/SupplierViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/supplier/SupplierViewModel.cs new file mode 100644 index 0000000..bf91935 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/supplier/SupplierViewModel.cs @@ -0,0 +1,114 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// supplier viewModel + /// + public class SupplierViewModel + { + + #region constructor + /// + /// constructor + /// + public SupplierViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// supplier_name + /// + [Display(Name = "supplier_name")] + [MaxLength(256,ErrorMessage = "MaxLength")] + [Required(ErrorMessage = "Required")] + public string supplier_name { get; set; } = string.Empty; + + /// + /// city + /// + [Display(Name = "city")] + [MaxLength(128,ErrorMessage = "MaxLength")] + public string city { get; set; } = string.Empty; + + /// + /// address + /// + [Display(Name = "address")] + [MaxLength(256,ErrorMessage = "MaxLength")] + public string address { get; set; } = string.Empty; + + /// + /// email + /// + [Display(Name = "email")] + [MaxLength(128,ErrorMessage = "MaxLength")] + public string email { get; set; } = string.Empty; + + /// + /// manager + /// + [Display(Name = "manager")] + [MaxLength(64,ErrorMessage = "MaxLength")] + public string manager { get; set; } = string.Empty; + + /// + /// contact_tel + /// + [Display(Name = "contact_tel")] + [MaxLength(64,ErrorMessage = "MaxLength")] + public string contact_tel { get; set; } = string.Empty; + + /// + /// creator + /// + [Display(Name = "creator")] + [MaxLength(64,ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// is_valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } =true; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/userrole/UserroleViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/userrole/UserroleViewModel.cs new file mode 100644 index 0000000..cbfe7c3 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/userrole/UserroleViewModel.cs @@ -0,0 +1,71 @@ +/* + * date:2022-12-20 + * developer:NoNo + */ +using System; +using System.ComponentModel.DataAnnotations; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// userrole viewModel + /// + public class UserroleViewModel + { + + #region constructor + /// + /// constructor + /// + public UserroleViewModel() + { + + } + #endregion + #region Property + + /// + /// id + /// + [Display(Name = "id")] + public int id { get; set; } = 0; + + /// + /// role_name + /// + [Display(Name = "role_name")] + [MaxLength(32,ErrorMessage = "MaxLength")] + public string role_name { get; set; } = string.Empty; + + /// + /// is_valid + /// + [Display(Name = "is_valid")] + public bool is_valid { get; set; } = false; + + /// + /// create_time + /// + [Display(Name = "create_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; + + /// + /// last_update_time + /// + [Display(Name = "last_update_time")] + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + + /// + /// tenant_id + /// + [Display(Name = "tenant_id")] + public long tenant_id { get; set; } = 0; + + + #endregion + + } +} diff --git a/backend/ModernWMS.WMS/IServices/Asn/IAsnService.cs b/backend/ModernWMS.WMS/IServices/Asn/IAsnService.cs new file mode 100644 index 0000000..92f8781 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Asn/IAsnService.cs @@ -0,0 +1,128 @@ +/* + * date:2022-12-22 + * developer:AMo + */ +using Microsoft.EntityFrameworkCore; +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; +using ModernWMS.Core.Services; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + +namespace ModernWMS.WMS.IServices +{ + /// + /// Interface of AsnService + /// + public interface IAsnService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel + /// currentUser + /// + Task<(int id, string msg)> AddAsync(AsnViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// viewmodel + /// + Task<(bool flag, string msg)> UpdateAsync(AsnViewModel viewModel); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + + /// + /// Bulk modify Goodsowner + /// + /// args + /// + Task<(bool flag, string msg)> BulkModifyGoodsownerAsync(AsnBulkModifyGoodsOwnerViewModel viewModel); + #endregion + + #region Flow Api + /// + /// Confirm Delivery + /// change the asn_status from 0 to 1 + /// + /// id + /// + Task<(bool flag, string msg)> ConfirmAsync(int id); + + /// + /// Cancel confirm, change asn_status 1 to 0 + /// + /// id + /// + Task<(bool flag, string msg)> ConfirmCancelAsync(int id); + + /// + /// Unload + /// change the asn_status from 1 to 2 + /// + /// id + /// + Task<(bool flag, string msg)> UnloadAsync(int id); + + /// + /// Cancel unload + /// change the asn_status from 2 to 1 + /// + /// id + /// + Task<(bool flag, string msg)> UnloadCancelAsync(int id); + + /// + /// sorting, add a new asnsort record and update asn sorted_qty + /// + /// args + /// currentUser + /// + Task<(bool flag, string msg)> SortingAsync(AsnsortInputViewModel viewModel, CurrentUser currentUser); + /// + /// Sorted + /// change the asn_status from 2 to 3 + /// + /// id + /// + Task<(bool flag, string msg)> SortedAsync(int id); + + /// + /// Cancel sorted + /// change the asn_status from 3 to 2 + /// + /// id + /// + Task<(bool flag, string msg)> SortedCancelAsync(int id); + + /// + /// PutAway + /// + /// args + /// currentUser + /// + Task<(bool flag, string msg)> PutAwayAsync(AsnPutAwayInputViewModel viewModel, CurrentUser currentUser); + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/IServices/Customer/ICustomerService.cs b/backend/ModernWMS.WMS/IServices/Customer/ICustomerService.cs new file mode 100644 index 0000000..9deae66 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Customer/ICustomerService.cs @@ -0,0 +1,66 @@ +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; + +namespace ModernWMS.WMS.IServices +{ + /// + /// Interface of CustomerService + /// + public interface ICustomerService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get all records + /// + /// currentUser + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// id + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// args + /// currentUser + /// + Task<(int id, string msg)> AddAsync(CustomerViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// args + /// + Task<(bool flag, string msg)> UpdateAsync(CustomerViewModel viewModel); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + #endregion + + #region Import + /// + /// import customers by excel + /// + /// excel data + /// currentUser + /// + Task<(bool flag, List errorData)> ExcelAsync(List input, CurrentUser currentUser); + #endregion + } +} diff --git a/backend/ModernWMS.WMS/IServices/Dispatchlist/IDispatchlistService.cs b/backend/ModernWMS.WMS/IServices/Dispatchlist/IDispatchlistService.cs new file mode 100644 index 0000000..0b05c11 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Dispatchlist/IDispatchlistService.cs @@ -0,0 +1,155 @@ +/* + * date:2022-12-27 + * developer:NoNo + */ + using ModernWMS.Core.Services; + using ModernWMS.Core.Models; + using ModernWMS.Core.JWT; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; +namespace ModernWMS.WMS.IServices +{ + /// + /// Interface of DispatchlistService + /// + public interface IDispatchlistService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + + /// + /// advanced dispatch order page search + /// + /// args + /// currentUser + /// + Task<(List data, int totals)> AdvancedDispatchlistPageAsync(PageSearch pageSearch, CurrentUser currentUser); + + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + Task<(bool flag, string msg)> AddAsync(List viewModel, CurrentUser currentUser); + + /// + /// Dispatchlist details with available stock + /// + /// dispatch_no + /// current user + /// + Task> ConfirmOrderCheck(string dispatch_no, CurrentUser currentUser); + + /// + /// get dispatchlist by dispatch_no + /// + /// + /// + /// + Task> GetByDispatchlistNo(string dispatch_no, CurrentUser currentUser); + + /// + /// delete a record + /// + /// dispatch_no + /// current user + /// + Task<(bool flag, string msg)> DeleteAsync(string dispatch_no, CurrentUser currentUser); + + /// + /// update dispatchlist with same dispatch_no + /// + /// + /// + /// + Task<(bool flag, string msg)> UpdateAsycn(List viewModels, CurrentUser currentUser); + + /// + /// Confirm orders and create dispatchpicklist + /// + /// viewModels + /// current user + /// + Task<(bool flag, string msg)> ConfirmOrder(List viewModels, CurrentUser currentUser); + + /// + /// confirm dispatchpicklist picked by dispatch_no + /// + /// dispatch_no + /// current user + /// + Task<(bool flag, string msg)> ConfirmPickByDispatchNo(string dispatch_no, CurrentUser currentUser); + + /// + /// package + /// + /// viewModels + /// currentUser + /// + /// + Task<(bool flag, string msg)> Package(List viewModels, CurrentUser currentUser); + + /// + /// weight + /// + /// viewModels + /// currentUser + /// + /// + Task<(bool flag, string msg)> Weight(List viewModels, CurrentUser currentUser); + + /// + /// dispatchpicklist outbound delivery + /// + /// viewModels + /// currentUser + /// + /// + Task<(bool flag, string msg)> Delivery(List viewModels, CurrentUser currentUser); + + /// + /// set dispatchlist freightfee + /// + /// + /// + Task<(bool flag, string msg)> SetFreightfee(List viewModels); + + /// + /// sign for arrival + /// + /// viewModels + /// + Task<(bool flag, string msg)> SignForArrival(List viewModels); + + /// + /// get pick list by dispatch_id + /// + /// dispatch_id + /// + Task> GetPickListByDispatchID(int dispatch_id); + + /// + /// cancel order opration + /// + /// viewmodel + /// current user + /// + Task<(bool flag, string msg)> CancelOrderOpration(CancelOrderOprationViewModel viewModel, CurrentUser currentUser); + + /// + /// cancel dispatchlist detail opration + /// + /// dispatchlist_id + /// + Task<(bool flag, string msg)> CancelDispatchlistDetailOpration(int id); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/Freightfee/IFreightfeeService.cs b/backend/ModernWMS.WMS/IServices/Freightfee/IFreightfeeService.cs new file mode 100644 index 0000000..bbb2707 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Freightfee/IFreightfeeService.cs @@ -0,0 +1,68 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ + using ModernWMS.Core.Services; + using ModernWMS.Core.Models; + using ModernWMS.Core.JWT; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + + namespace ModernWMS.WMS.IServices + { + /// + /// Interface of FreightfeeService + /// + public interface IFreightfeeService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get all records + /// + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + Task<(int id, string msg)> AddAsync(FreightfeeViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// viewmodel + /// + Task<(bool flag, string msg)> UpdateAsync(FreightfeeViewModel viewModel); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + + /// + /// import freightfee by excel + /// + /// excel datas + /// current user + /// + Task<(bool flag, string msg)> ExcelAsync(List datas, CurrentUser currentUser); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/GoodsOwner/IGoodsownerService.cs b/backend/ModernWMS.WMS/IServices/GoodsOwner/IGoodsownerService.cs new file mode 100644 index 0000000..f72fd1f --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/GoodsOwner/IGoodsownerService.cs @@ -0,0 +1,66 @@ +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; + +namespace ModernWMS.WMS.IServices +{ + /// + /// Interface of GoodsownerService + /// + public interface IGoodsownerService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get all records + /// + /// currentUser + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// id + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// args + /// currentUser + /// + Task<(int id, string msg)> AddAsync(GoodsownerViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// args + /// + Task<(bool flag, string msg)> UpdateAsync(GoodsownerViewModel viewModel); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + #endregion + + #region Import + /// + /// import goodsowners by excel + /// + /// excel data + /// currentUser + /// + Task<(bool flag, List errorData)> ExcelAsync(List input, CurrentUser currentUser); + #endregion + } +} diff --git a/backend/ModernWMS.WMS/IServices/Goodslocation/IGoodslocationService.cs b/backend/ModernWMS.WMS/IServices/Goodslocation/IGoodslocationService.cs new file mode 100644 index 0000000..c88a8e7 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Goodslocation/IGoodslocationService.cs @@ -0,0 +1,70 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ + using ModernWMS.Core.Services; + using ModernWMS.Core.Models; + using ModernWMS.Core.JWT; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + + namespace ModernWMS.WMS.IServices + { + /// + /// Interface of GoodslocationService + /// + public interface IGoodslocationService : IBaseService + { + #region Api + /// + /// get goodslocation of the warehousearea by warehouse_id and warehousearea_id + /// + /// warehousearea's id + /// current user + /// + Task> GetGoodslocationByWarehouse_area_id(int warehousearea_id, CurrentUser currentUser); + + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get all records + /// + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + Task<(int id, string msg)> AddAsync(GoodslocationViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// viewmodel + /// currentUser + /// + Task<(bool flag, string msg)> UpdateAsync(GoodslocationViewModel viewModel, CurrentUser currentUser); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/Rolemenu/IRolemenuService.cs b/backend/ModernWMS.WMS/IServices/Rolemenu/IRolemenuService.cs new file mode 100644 index 0000000..e1dd33e --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Rolemenu/IRolemenuService.cs @@ -0,0 +1,66 @@ +using ModernWMS.Core.JWT; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; + +namespace ModernWMS.WMS.IServices +{ + /// + /// Interface of RolemenuService + /// + public interface IRolemenuService : IBaseService + { + #region Api + /// + /// Get all records + /// + /// currentUser + /// + Task> GetAllAsync(CurrentUser currentUser); + + /// + /// Get a record by id + /// + /// userrole id + /// + Task GetAsync(int userrole_id); + + /// + /// add a new record + /// + /// args + /// currentUser + /// + Task<(int id, string msg)> AddAsync(RolemenuBothViewModel viewModel, CurrentUser currentUser); + + /// + /// Get all menus + /// + /// currentUser + /// + Task> GetAllMenusAsync(CurrentUser currentUser); + + /// + /// Get menu's authority by user role id + /// + /// user role id + /// + Task> GetMenusByRoleId(int userrole_id); + + /// + /// update a record + /// + /// args + /// currentUser + /// + Task<(bool flag, string msg)> UpdateAsync(RolemenuBothViewModel viewModel, CurrentUser currentUser); + + /// + /// delete a record + /// + /// userrole id + /// + Task<(bool flag, string msg)> DeleteAsync(int userrole_id); + #endregion + } +} diff --git a/backend/ModernWMS.WMS/IServices/Sku/ICategoryService.cs b/backend/ModernWMS.WMS/IServices/Sku/ICategoryService.cs new file mode 100644 index 0000000..594f401 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Sku/ICategoryService.cs @@ -0,0 +1,53 @@ +/* + * date:2022-12-20 + * developer:AMo + */ +using ModernWMS.Core.JWT; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; + +namespace ModernWMS.WMS.IServices +{ + /// + /// Interface of CategoryService + /// + public interface ICategoryService : IBaseService + { + #region Api + /// + /// Get all records + /// + /// currentUser + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel + /// currentUser + /// + Task<(int id, string msg)> AddAsync(CategoryViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// viewmodel + /// + Task<(bool flag, string msg)> UpdateAsync(CategoryViewModel viewModel); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/IServices/Sku/ISpuService.cs b/backend/ModernWMS.WMS/IServices/Sku/ISpuService.cs new file mode 100644 index 0000000..1b065fb --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Sku/ISpuService.cs @@ -0,0 +1,61 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; + + namespace ModernWMS.WMS.IServices + { + /// + /// Interface of SpuService + /// + public interface ISpuService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// get sku info by sku_id + /// + /// sku_id + /// + Task GetSkuAsync(int sku_id); + /// + /// add a new record + /// + /// viewmodel + /// currentUser + /// + Task<(int id, string msg)> AddAsync(SpuBothViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// viewmodel + /// + Task<(bool flag, string msg)> UpdateAsync(SpuBothViewModel viewModel); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/Stock/IStockService.cs b/backend/ModernWMS.WMS/IServices/Stock/IStockService.cs new file mode 100644 index 0000000..f97b0c8 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Stock/IStockService.cs @@ -0,0 +1,51 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ + using ModernWMS.Core.Services; + using ModernWMS.Core.Models; + using ModernWMS.Core.JWT; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; +namespace ModernWMS.WMS.IServices +{ + /// + /// Interface of StockService + /// + public interface IStockService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> StockPageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// location stock page search + /// + /// args + /// currentUser + /// + Task<(List data, int totals)> LocationStockPageAsync(PageSearch pageSearch, CurrentUser currentUser); + + /// + /// page search select + /// + /// args + /// currentUser + /// + Task<(List data, int totals)> SelectPageAsync(PageSearch pageSearch, CurrentUser currentUser); + + /// + /// sku page search select + /// + /// args + /// currentUser + /// + Task<(List data, int totals)> SkuSelectPageAsync(PageSearch pageSearch, CurrentUser currentUser); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/Stockadjust/IStockadjustService.cs b/backend/ModernWMS.WMS/IServices/Stockadjust/IStockadjustService.cs new file mode 100644 index 0000000..ea98ecc --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Stockadjust/IStockadjustService.cs @@ -0,0 +1,68 @@ +/* + * date:2022-12-26 + * developer:NoNo + */ + using ModernWMS.Core.Services; + using ModernWMS.Core.Models; + using ModernWMS.Core.JWT; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + + namespace ModernWMS.WMS.IServices + { + /// + /// Interface of StockadjustService + /// + public interface IStockadjustService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get all records + /// + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + Task<(int id, string msg)> AddAsync(StockadjustViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// viewmodel + /// + Task<(bool flag, string msg)> UpdateAsync(StockadjustViewModel viewModel); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + + + /// + /// confirm adjustment + /// + /// id + /// + Task<(bool flag, string msg)> ConfirmAdjustment(int id); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/Stockfreeze/IStockfreezeService.cs b/backend/ModernWMS.WMS/IServices/Stockfreeze/IStockfreezeService.cs new file mode 100644 index 0000000..0f8d900 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Stockfreeze/IStockfreezeService.cs @@ -0,0 +1,60 @@ +/* + * date:2022-12-26 + * developer:NoNo + */ + using ModernWMS.Core.Services; + using ModernWMS.Core.Models; + using ModernWMS.Core.JWT; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + + namespace ModernWMS.WMS.IServices + { + /// + /// Interface of StockfreezeService + /// + public interface IStockfreezeService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get all records + /// + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + Task<(int id, string msg)> AddAsync(StockfreezeViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// viewmodel + /// + Task<(bool flag, string msg)> UpdateAsync(StockfreezeViewModel viewModel); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/Stockmove/IStockmoveService.cs b/backend/ModernWMS.WMS/IServices/Stockmove/IStockmoveService.cs new file mode 100644 index 0000000..a166a3d --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Stockmove/IStockmoveService.cs @@ -0,0 +1,60 @@ +/* + * date:2022-12-27 + * developer:NoNo + */ + using ModernWMS.Core.Services; + using ModernWMS.Core.Models; + using ModernWMS.Core.JWT; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + + namespace ModernWMS.WMS.IServices + { + /// + /// Interface of StockmoveService + /// + public interface IStockmoveService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get all records + /// + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + Task<(int id, string msg)> AddAsync(StockmoveViewModel viewModel, CurrentUser currentUser); + /// + /// confirm move + /// + /// id + /// + Task<(bool flag, string msg)> Confirm(int id, CurrentUser currentUser); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/Stockprocess/IStockprocessService.cs b/backend/ModernWMS.WMS/IServices/Stockprocess/IStockprocessService.cs new file mode 100644 index 0000000..fd7de78 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Stockprocess/IStockprocessService.cs @@ -0,0 +1,76 @@ +/* + * date:2022-12-23 + * developer:NoNo + */ + using ModernWMS.Core.Services; + using ModernWMS.Core.Models; + using ModernWMS.Core.JWT; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + + namespace ModernWMS.WMS.IServices + { + /// + /// Interface of StockprocessService + /// + public interface IStockprocessService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get all records + /// + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + Task<(int id, string msg)> AddAsync(StockprocessViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// viewmodel + /// + Task<(bool flag, string msg)> UpdateAsync(StockprocessViewModel viewModel); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + + /// + /// confirm processing + /// + /// id + /// + Task<(bool flag, string msg)> ConfirmProcess(int id, CurrentUser currentUser); + + + /// + /// confirm adjustment + /// + /// id + /// current user + /// + Task<(bool flag, string msg)> ConfirmAdjustment(int id, CurrentUser currentUser); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/Stocktaking/IStocktakingService.cs b/backend/ModernWMS.WMS/IServices/Stocktaking/IStocktakingService.cs new file mode 100644 index 0000000..c2ce239 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Stocktaking/IStocktakingService.cs @@ -0,0 +1,66 @@ +/* + * date:2022-12-30 + * developer:AMo + */ +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; +using ModernWMS.Core.Services; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + + namespace ModernWMS.WMS.IServices + { + /// + /// Interface of StocktakingService + /// + public interface IStocktakingService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel + /// currentUser + /// + Task<(int id, string msg)> AddAsync(StocktakingBasicViewModel viewModel, CurrentUser currentUser); + + /// + /// update counted_qty + /// + /// args + /// currentUser + /// + Task<(bool flag, string msg)> PutAsync(StocktakingConfirmViewModel viewModel, CurrentUser currentUser); + + /// + /// confrim a record and change stock and add to stockadjust + /// + /// id + /// currentUser + /// + Task<(bool flag, string msg)> ConfirmAsync(int id, CurrentUser currentUser); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/Warehouse/IWarehouseService.cs b/backend/ModernWMS.WMS/IServices/Warehouse/IWarehouseService.cs new file mode 100644 index 0000000..2532a00 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Warehouse/IWarehouseService.cs @@ -0,0 +1,75 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ + using ModernWMS.Core.Services; + using ModernWMS.Core.Models; + using ModernWMS.Core.JWT; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + + namespace ModernWMS.WMS.IServices + { + /// + /// Interface of WarehouseService + /// + public interface IWarehouseService : IBaseService + { + #region Api + /// + /// get select items + /// + /// current user + /// + Task> GetSelectItemsAsnyc(CurrentUser currentUser); + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get all records + /// + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + Task<(int id, string msg)> AddAsync(WarehouseViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// viewmodel + /// currentUser + /// + Task<(bool flag, string msg)> UpdateAsync(WarehouseViewModel viewModel, CurrentUser currentUser); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + + /// + /// import warehouses by excel + /// + /// excel datas + /// current user + /// + Task<(bool flag, string msg)> ExcelAsync(List datas, CurrentUser currentUser); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/Warehousearea/IWarehouseareaService.cs b/backend/ModernWMS.WMS/IServices/Warehousearea/IWarehouseareaService.cs new file mode 100644 index 0000000..9abcd65 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/Warehousearea/IWarehouseareaService.cs @@ -0,0 +1,69 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ + using ModernWMS.Core.Services; + using ModernWMS.Core.Models; + using ModernWMS.Core.JWT; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + + namespace ModernWMS.WMS.IServices + { + /// + /// Interface of WarehouseareaService + /// + public interface IWarehouseareaService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get all records + /// + /// + Task> GetAllAsync(int warehouse_id, CurrentUser currentUser); + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + Task<(int id, string msg)> AddAsync(WarehouseareaViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// viewmodel + /// currentUser + /// + Task<(bool flag, string msg)> UpdateAsync(WarehouseareaViewModel viewModel, CurrentUser currentUser); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + + /// + /// get warehouseareas of the warehouse by warehouse_id + /// + /// warehouse's id + /// current user + /// + Task> GetWarehouseareaByWarehouse_id(int warehouse_id, CurrentUser currentUser); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/company/ICompanyService.cs b/backend/ModernWMS.WMS/IServices/company/ICompanyService.cs new file mode 100644 index 0000000..262d774 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/company/ICompanyService.cs @@ -0,0 +1,48 @@ +using ModernWMS.Core.JWT; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; + +namespace ModernWMS.WMS.IServices +{ + /// + /// Interface of CompanyService + /// + public interface ICompanyService : IBaseService + { + #region Api + /// + /// Get all records + /// + /// currentUser + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// id + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// args + /// currentUser + /// + Task<(int id, string msg)> AddAsync(CompanyViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// args + /// + Task<(bool flag, string msg)> UpdateAsync(CompanyViewModel viewModel); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + #endregion + } +} diff --git a/backend/ModernWMS.WMS/IServices/supplier/ISupplierService.cs b/backend/ModernWMS.WMS/IServices/supplier/ISupplierService.cs new file mode 100644 index 0000000..a404513 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/supplier/ISupplierService.cs @@ -0,0 +1,68 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; +using ModernWMS.Core.Services; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; +namespace ModernWMS.WMS.IServices +{ + /// + /// Interface of SupplierService + /// + public interface ISupplierService : IBaseService + { + #region Api + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get all records + /// + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + Task<(int id, string msg)> AddAsync(SupplierViewModel viewModel, CurrentUser currentUser); + /// + /// update a record + /// + /// viewmodel + /// currentUser + /// + Task<(bool flag, string msg)> UpdateAsync(SupplierViewModel viewModel, CurrentUser currentUser); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + + /// + /// import suppliers by excel + /// + /// excel datas + /// current user + /// + Task<(bool flag, string msg)> ExcelAsync(List datas, CurrentUser currentUser); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/user/IUserService.cs b/backend/ModernWMS.WMS/IServices/user/IUserService.cs new file mode 100644 index 0000000..9f40fb0 --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/user/IUserService.cs @@ -0,0 +1,95 @@ +/* + * date:2022-12-20 + * developer:NoNo + */ + using ModernWMS.Core.Services; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.Core.Models; +using ModernWMS.Core.JWT; + +namespace ModernWMS.WMS.IServices +{ + /// + /// Interface of UserService + /// + public interface IUserService : IBaseService + { + #region Api + /// + /// get select items + /// + /// current user + /// + Task> GetSelectItemsAsnyc(CurrentUser currentUser); + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// + /// Get all datas + /// + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a data by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new data + /// + /// viewmodel + /// + Task<(int id, string msg)> AddAsync(UserViewModel viewModel, CurrentUser currentUser); + /// + /// update a data + /// + /// viewmodel + /// currentUser + /// + Task<(bool flag, string msg)> UpdateAsync(UserViewModel viewModel, CurrentUser currentUser); + + /// + /// delete a data + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + + /// + /// import users by excel + /// + /// excel datas + /// current user + /// + Task<(bool flag, string msg)> ExcelAsync(List datas,CurrentUser currentUser); + + /// + /// reset password + /// + /// viewmodel + /// + Task<(bool, string)> ResetPwd(BatchOperationViewModel viewModel); + + /// + /// change password + /// + /// viewmodel + /// + Task<(bool flag, string msg)> ChangePwd(UserChangePwdViewModel viewModel); + + /// + /// register a new tenant + /// + /// viewModel + /// + Task<(bool flag, string msg)> Register(RegisterViewModel viewModel); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/IServices/userrole/IUserroleService.cs b/backend/ModernWMS.WMS/IServices/userrole/IUserroleService.cs new file mode 100644 index 0000000..2e0bfdc --- /dev/null +++ b/backend/ModernWMS.WMS/IServices/userrole/IUserroleService.cs @@ -0,0 +1,60 @@ +/* + * date:2022-12-20 + * developer:NoNo + */ +using ModernWMS.Core.JWT; +using ModernWMS.Core.Services; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.Core.Models; + namespace ModernWMS.WMS.IServices + { + /// + /// Interface of UserroleService + /// + public interface IUserroleService : IBaseService + { + #region Api + /// + /// bulk save records + /// + /// viewmodel + /// current user + /// + Task<(bool flag, string msg)> BulkSaveAsync(List viewModels, CurrentUser currentUser); + /// + /// Get all records + /// + /// + Task> GetAllAsync(CurrentUser currentUser); + /// + /// Get a record by id + /// + /// primary key + /// + Task GetAsync(int id); + /// + /// add a new record + /// + /// viewmodel> + /// current user> + /// + Task<(int id, string msg)> AddAsync(UserroleViewModel viewModel,CurrentUser currentUser); + /// + /// update a record + /// + /// viewmodel + /// currentUser + /// + Task<(bool flag, string msg)> UpdateAsync(UserroleViewModel viewModel, CurrentUser currentUser); + + /// + /// delete a record + /// + /// id + /// + Task<(bool flag, string msg)> DeleteAsync(int id); + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/ModernWMS.WMS.csproj b/backend/ModernWMS.WMS/ModernWMS.WMS.csproj new file mode 100644 index 0000000..c24705c --- /dev/null +++ b/backend/ModernWMS.WMS/ModernWMS.WMS.csproj @@ -0,0 +1,14 @@ + + + + net7.0 + enable + enable + True + + + + + + + diff --git a/backend/ModernWMS.WMS/Services/Asn/AsnService.cs b/backend/ModernWMS.WMS/Services/Asn/AsnService.cs new file mode 100644 index 0000000..282b66d --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Asn/AsnService.cs @@ -0,0 +1,656 @@ +/* + * date:2022-12-22 + * developer:AMo + */ +using Mapster; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.DynamicSearch; +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; + +namespace ModernWMS.WMS.Services +{ + /// + /// Asn Service + /// + public class AsnService : BaseService, IAsnService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Asn constructor + /// + /// The DBContext + /// Localizer + public AsnService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search, sqlTitle input asn_status:0 ~ 4 + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + Byte asn_status = 255; + if (pageSearch.sqlTitle.ToLower().Contains("asn_status")) + { + asn_status = Convert.ToByte(pageSearch.sqlTitle.Trim().ToLower().Replace("asn_status","").Replace(":", "").Replace(":", "").Replace("=", "")); + asn_status = asn_status.Equals(4) ? (Byte)255 : asn_status; + } + var Spus = _dBContext.GetDbSet(); + var Skus = _dBContext.GetDbSet(); + var Asns = _dBContext.GetDbSet(); + var query = from m in Asns.AsNoTracking() + join p in Spus.AsNoTracking() on m.spu_id equals p.id + join k in Skus.AsNoTracking() on m.sku_id equals k.id + where m.tenant_id == currentUser.tenant_id + && (asn_status == 255 || m.asn_status == asn_status) + select new AsnViewModel + { + id = m.id, + asn_no = m.asn_no, + asn_status = m.asn_status, + spu_id = m.spu_id, + spu_code = p.spu_code, + spu_name = p.spu_name, + sku_id = m.sku_id, + sku_code = k.sku_code, + sku_name = k.sku_name, + origin = p.origin, + length_unit = p.length_unit, + volume_unit = p.volume_unit, + weight_unit = p.weight_unit, + asn_qty = m.asn_qty, + actual_qty = m.actual_qty, + sorted_qty = m.sorted_qty, + shortage_qty = m.shortage_qty, + more_qty = m.more_qty, + damage_qty = m.damage_qty, + weight = k.weight * m.asn_qty, + volume = k.volume * m.asn_qty, + supplier_id = m.supplier_id, + supplier_name = m.supplier_name, + goods_owner_id = m.goods_owner_id, + goods_owner_name = m.goods_owner_name, + creator = m.creator, + create_time = m.create_time, + last_update_time = m.last_update_time, + is_valid = m.is_valid + }; + query = query.Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var Spus = _dBContext.GetDbSet(); + var Skus = _dBContext.GetDbSet(); + var Asns = _dBContext.GetDbSet(); + var query = from m in Asns.AsNoTracking() + join p in Spus.AsNoTracking() on m.spu_id equals p.id + join k in Skus.AsNoTracking() on m.sku_id equals k.id + select new AsnViewModel + { + id = m.id, + asn_no = m.asn_no, + asn_status = m.asn_status, + spu_id = m.spu_id, + spu_code = p.spu_code, + spu_name = p.spu_name, + sku_id = m.sku_id, + sku_code = k.sku_code, + sku_name = k.sku_name, + origin = p.origin, + length_unit = p.length_unit, + volume_unit = p.volume_unit, + weight_unit = p.weight_unit, + asn_qty = m.asn_qty, + actual_qty = m.actual_qty, + sorted_qty = m.sorted_qty, + shortage_qty = m.shortage_qty, + more_qty = m.more_qty, + damage_qty = m.damage_qty, + weight = m.weight, + volume = m.volume, + supplier_id = m.supplier_id, + supplier_name = m.supplier_name, + goods_owner_id = m.goods_owner_id, + goods_owner_name = m.goods_owner_name, + creator = m.creator, + create_time = m.create_time, + last_update_time = m.last_update_time, + is_valid = m.is_valid + }; + var data = await query.FirstOrDefaultAsync(t => t.id.Equals(id)); + return data ?? new AsnViewModel(); + } + /// + /// add a new record + /// + /// viewmodel + /// currentUser + /// + public async Task<(int id, string msg)> AddAsync(AsnViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var entity = viewModel.Adapt(); + entity.id = 0; + entity.asn_no = await GetOrderCode(currentUser); + entity.creator = currentUser.user_name; + entity.create_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + entity.is_valid = viewModel.is_valid; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + + /// + /// get next code number + /// + /// currentUser + /// + public async Task GetOrderCode(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + string code = ""; + string date = DateTime.Now.ToString("yyyy" + "MM" + "dd"); + string maxNo = await DbSet.AsNoTracking().Where(t => t.tenant_id.Equals(currentUser.tenant_id)).MaxAsync(t => t.asn_no); + if (string.IsNullOrEmpty(maxNo)) + { + code = date + "-0001"; + } + else + { + try + { + string maxDate = maxNo[..8]; + string maxDateNo = maxNo[9..]; + if (date == maxDate) + { + int.TryParse(maxDateNo, out int dd); + int newDateNo = dd + 1; + code = date + "-" + newDateNo.ToString("0000"); + } + else + { + code = date + "-0001"; + } + } + catch + { + code = date + "-0001"; + } + } + + return code; + } + /// + /// update a record + /// + /// args + /// + public async Task<(bool flag, string msg)> UpdateAsync(AsnViewModel viewModel) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + entity.id = viewModel.id; + entity.asn_no = viewModel.asn_no; + entity.spu_id = viewModel.spu_id; + entity.sku_id = viewModel.sku_id; + entity.asn_qty = viewModel.asn_qty; + entity.weight = viewModel.weight; + entity.volume = viewModel.volume; + entity.supplier_id = viewModel.supplier_id; + entity.supplier_name = viewModel.supplier_name; + entity.goods_owner_id = viewModel.goods_owner_id; + entity.goods_owner_name = viewModel.goods_owner_name; + entity.is_valid = viewModel.is_valid; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var Asns = _dBContext.GetDbSet(); + var entity = await Asns.FirstOrDefaultAsync(t => t.id.Equals(id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + if (entity.asn_status.Equals(0)) + { + Asns.Remove(entity); + } + else if (entity.asn_status.Equals(8)) + { + return (false, _stringLocalizer["asn_had_putaway"]); + } + else + { + entity.asn_status = (byte)(entity.asn_status - 1); + } + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + + /// + /// Bulk modify Goodsowner + /// + /// args + /// + public async Task<(bool flag, string msg)> BulkModifyGoodsownerAsync(AsnBulkModifyGoodsOwnerViewModel viewModel) + { + var Asns = _dBContext.GetDbSet(); + var entities = await Asns.Where(t => viewModel.idList.Contains(t.id)).ToListAsync(); + //需要什么限制? + entities.ForEach(t => + { + t.goods_owner_id = viewModel.goods_owner_id; + t.goods_owner_name = viewModel.goods_owner_name; + t.last_update_time = DateTime.Now; + }); + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + #endregion + + #region Flow Api + /// + /// Confirm Delivery + /// change the asn_status from 0 to 1 + /// + /// id + /// + public async Task<(bool flag, string msg)> ConfirmAsync(int id) + { + var Asns = _dBContext.GetDbSet(); + var entity = await Asns.FirstOrDefaultAsync(t => t.id == id); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + else if (entity.asn_status > 0) + { + return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Delivery"]}"); + } + entity.asn_status = 1; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["confirm_success"]); + } + else + { + return (false, _stringLocalizer["confirm_failed"]); + } + } + /// + /// Cancel confirm, change asn_status 1 to 0 + /// + /// id + /// + public async Task<(bool flag, string msg)> ConfirmCancelAsync(int id) + { + var Asns = _dBContext.GetDbSet(); + var entity = await Asns.FirstOrDefaultAsync(t => t.id == id); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + else if (entity.asn_status != (byte)1) + { + return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Delivery"]}"); + } + entity.asn_status = 0; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + + /// + /// Unload + /// change the asn_status from 1 to 2 + /// + /// id + /// + public async Task<(bool flag, string msg)> UnloadAsync(int id) + { + var Asns = _dBContext.GetDbSet(); + var entity = await Asns.FirstOrDefaultAsync(t => t.id == id); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + else if (entity.asn_status > 1) + { + return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Load"]}"); + } + entity.asn_status = 2; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["confirm_success"]); + } + else + { + return (false, _stringLocalizer["confirm_failed"]); + } + } + + /// + /// Cancel unload + /// change the asn_status from 2 to 1 + /// + /// id + /// + public async Task<(bool flag, string msg)> UnloadCancelAsync(int id) + { + var Asns = _dBContext.GetDbSet(); + var entity = await Asns.FirstOrDefaultAsync(t => t.id == id); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + else if (entity.asn_status != (byte)2) + { + return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Load"]}"); + } + entity.asn_status = 1; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// sorting, add a new asnsort record and update asn sorted_qty + /// + /// args + /// currentUser + /// + public async Task<(bool flag, string msg)> SortingAsync(AsnsortInputViewModel viewModel, CurrentUser currentUser) + { + var Asns = _dBContext.GetDbSet(); + var Asnsorts = _dBContext.GetDbSet(); + + var entity = await Asns.FirstOrDefaultAsync(t => t.id == viewModel.asn_id); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + else if (entity.asn_status != 2) + { + return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Sort"]}"); + } + await Asnsorts.AddAsync(new AsnsortEntity + { + id = 0, + asn_id = viewModel.asn_id, + sorted_qty = viewModel.sorted_qty, + create_time = DateTime.Now, + creator = currentUser.user_name, + is_valid = true, + last_update_time = DateTime.Now, tenant_id = currentUser.tenant_id + }); + entity.sorted_qty += viewModel.sorted_qty; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// Sorted + /// change the asn_status from 2 to 3 + /// + /// id + /// + public async Task<(bool flag, string msg)> SortedAsync(int id) + { + var Asns = _dBContext.GetDbSet(); + var entity = await Asns.FirstOrDefaultAsync(t => t.id == id); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + else if (entity.sorted_qty < 1) + { + return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Sorting"]}"); + } + entity.asn_status = 3; + if (entity.sorted_qty > entity.asn_qty) + { + entity.more_qty = entity.sorted_qty - entity.asn_qty; + } + else if (entity.sorted_qty < entity.asn_qty) + { + entity.shortage_qty = entity.asn_qty - entity.sorted_qty; + } + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["sorted_success"]); + } + else + { + return (false, _stringLocalizer["sorted_failed"]); + } + } + + /// + /// Cancel sorted + /// change the asn_status from 3 to 2 + /// + /// id + /// + public async Task<(bool flag, string msg)> SortedCancelAsync(int id) + { + var Asns = _dBContext.GetDbSet(); + var entity = await Asns.FirstOrDefaultAsync(t => t.id == id); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + else if (entity.actual_qty > 0) + { + return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Putaway"]}"); + } + else if (entity.sorted_qty < 1) + { + return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Sorting"]}"); + } + entity.asn_status = 2; + entity.sorted_qty = 0; + entity.more_qty = 0; + entity.shortage_qty = 0; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + var Asnsorts = _dBContext.GetDbSet(); + await Asnsorts.Where(t => t.asn_id.Equals(id)).ExecuteDeleteAsync(); + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// PutAway + /// + /// args + /// currentUser + /// + public async Task<(bool flag, string msg)> PutAwayAsync(AsnPutAwayInputViewModel viewModel, CurrentUser currentUser) + { + var Asns = _dBContext.GetDbSet(); + + var Goodslocations = _dBContext.GetDbSet(); + var Location = await Goodslocations.FirstOrDefaultAsync(t => t.id.Equals(viewModel.goods_location_id)); + if (Location == null) + { + return (false, string.Format(_stringLocalizer["Required"], _stringLocalizer["location_name"])); + } + + var entity = await Asns.FirstOrDefaultAsync(t => t.id == viewModel.asn_id); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + else if (entity.asn_status != 3) + { + return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Sorted"]}"); + } + else if (entity.actual_qty + viewModel.putaway_qty > entity.sorted_qty) + { + return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Total_PutAway_Qty_Greater_Than_Sorted_Qty"]}"); + } + entity.actual_qty += viewModel.putaway_qty; + if (Location.warehouse_area_property.Equals(5)) + { + entity.damage_qty += viewModel.putaway_qty; + } + if (entity.actual_qty.Equals(entity.sorted_qty)) + { + entity.asn_status = 4; + } + + entity.last_update_time = DateTime.Now; + var Stocks = _dBContext.GetDbSet(); + var stockEntity = await Stocks.FirstOrDefaultAsync(t => t.sku_id.Equals(entity.sku_id) && t.goods_location_id.Equals(viewModel.goods_location_id)); + if (stockEntity == null) + { + stockEntity = new StockEntity + { + sku_id = entity.sku_id, + goods_location_id = viewModel.goods_location_id, + goods_owner_id = entity.goods_owner_id, + qty = viewModel.putaway_qty, + is_freeze = false, + last_update_time = DateTime.Now, + tenant_id = currentUser.tenant_id, + id = 0 + }; + await Stocks.AddAsync(stockEntity); + } + else + { + stockEntity.qty += viewModel.putaway_qty; + stockEntity.last_update_time = DateTime.Now; + } + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["putaway_success"]); + } + else + { + return (false, _stringLocalizer["putaway_failed"]); + } + } + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/Services/Customer/CustomerService.cs b/backend/ModernWMS.WMS/Services/Customer/CustomerService.cs new file mode 100644 index 0000000..af9df62 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Customer/CustomerService.cs @@ -0,0 +1,249 @@ +using Mapster; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.DynamicSearch; +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using System.Linq; + +namespace ModernWMS.WMS.Services +{ + /// + /// customer Service + /// + public class CustomerService : BaseService, ICustomerService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localization + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// company service constructor + /// + /// The DBContext + /// Localization + public CustomerService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet(); + var query = DbSet.AsNoTracking() + .Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + .Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list.Adapt>(), totals); + } + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking().Where(t => t.tenant_id == currentUser.tenant_id) + .OrderByDescending(t => t.create_time).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// id + /// + public async Task GetAsync(int id) + { + var entity = await _dBContext.GetDbSet().AsNoTracking().FirstOrDefaultAsync(t => t.id.Equals(id)); + if (entity != null) + { + return entity.Adapt(); + } + else + { + return new CustomerViewModel(); + } + } + + /// + /// add a new record + /// + /// args + /// currentUser + /// + public async Task<(int id, string msg)> AddAsync(CustomerViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.tenant_id.Equals(currentUser.tenant_id) && t.customer_name.Equals(viewModel.customer_name))) + { + return (0, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["customer_name"], viewModel.customer_name)); + } + var entity = viewModel.Adapt(); + entity.id = 0; + entity.creator = currentUser.user_name; + entity.create_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// + public async Task<(bool flag, string msg)> UpdateAsync(CustomerViewModel viewModel) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + if (await DbSet.AnyAsync(t => !t.id.Equals(viewModel.id) && t.tenant_id.Equals(entity.tenant_id) && t.customer_name.Equals(viewModel.customer_name))) + { + return (false, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["customer_name"], viewModel.customer_name)); + } + entity.customer_name = viewModel.customer_name; + entity.city = viewModel.city; + entity.address = viewModel.address; + entity.email = viewModel.email; + entity.manager = viewModel.manager; + entity.contact_tel = viewModel.contact_tel; + entity.is_valid = viewModel.is_valid; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var Dispatchlists = _dBContext.GetDbSet(); + if(await Dispatchlists.AsNoTracking().AnyAsync(t => t.customer_id.Equals(id))) + { + return (false, _stringLocalizer["delete_referenced"]); + } + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + #endregion + + #region Import + /// + /// import customers by excel + /// + /// excel data + /// currentUser + /// + public async Task<(bool flag, List errorData)> ExcelAsync(List input, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var existsDatas = await DbSet.AsNoTracking().Where(t => t.tenant_id.Equals(currentUser.tenant_id)).Select(t => new { t.customer_name}).ToListAsync(); + input.ForEach(async t => + { + t.errorMsg = string.Empty; + if (existsDatas.Any(d => d.customer_name.Equals(t.customer_name))) + { + t.errorMsg = string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["customer_name"], t.customer_name); + } + else + { + await DbSet.AddAsync(new CustomerEntity + { + customer_name = t.customer_name, + city = t.city, + address = t.address, + email = t.email, + manager = t.manager, + contact_tel = t.contact_tel, + creator = currentUser.user_name, + create_time = DateTime.Now, + last_update_time = DateTime.Now, + is_valid = true, + tenant_id = currentUser.tenant_id + }); + } + }); + if (input.Any(t => t.errorMsg.Length > 0)) + { + return (false, input.Where(t => t.errorMsg.Length > 0).ToList()); + } + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, new List()); + } + else + { + return (false, new List()); + } + } + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Services/Dispatchlist/DispatchlistService.cs b/backend/ModernWMS.WMS/Services/Dispatchlist/DispatchlistService.cs new file mode 100644 index 0000000..70c85e0 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Dispatchlist/DispatchlistService.cs @@ -0,0 +1,1412 @@ +/* + * date:2022-12-27 + * developer:NoNo + */ +using Mapster; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.DynamicSearch; +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; +using ModernWMS.Core.Services; +using ModernWMS.Core.Utility; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using System.Collections.Generic; + +namespace ModernWMS.WMS.Services +{ + /// + /// Dispatchlist Service + /// + public class DispatchlistService : BaseService, IDispatchlistService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Dispatchlist constructor + /// + /// The DBContext + /// Localizer + public DispatchlistService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet(); + var query = from d in DbSet.AsNoTracking() + join sku in _dBContext.GetDbSet().AsNoTracking() on d.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + select new DispatchlistViewModel + { + id = d.id, + dispatch_no = d.dispatch_no, + dispatch_status = d.dispatch_status, + customer_id = d.customer_id, + customer_name = d.customer_name, + sku_id = d.sku_id, + qty = d.qty, + weight = d.weight, + volume = d.volume, + creator = d.creator, + create_time = d.create_time, + damage_qty = d.damage_qty, + lock_qty = d.lock_qty, + picked_qty = d.picked_qty, + intrasit_qty = d.intrasit_qty, + package_qty = d.package_qty, + unpackage_qty = d.picked_qty - d.package_qty, + weighing_qty = d.weighing_qty, + unweighing_qty = d.picked_qty - d.weighing_qty, + actual_qty = d.actual_qty, + sign_qty = d.sign_qty, + package_no = d.package_no, + package_person = d.package_person, + package_time = d.package_time, + weighing_no = d.weighing_no, + weighing_person = d.weighing_person, + weighing_weight = d.weighing_weight, + waybill_no = d.waybill_no, + carrier = d.carrier, + freightfee = d.freightfee, + last_update_time = d.last_update_time, + tenant_id = d.tenant_id, + sku_code = sku.sku_code, + spu_code = spu.spu_code, + spu_description = spu.spu_description, + spu_name = spu.spu_name, + bar_code = spu.bar_code, + unpicked_qty = d.qty - d.picked_qty, + length_unit = spu.length_unit, + volume_unit = spu.volume_unit, + weight_unit = spu.weight_unit + }; + query = query.Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + .Where(queries.AsExpression()); + if (pageSearch.sqlTitle.Contains("dispatch_status")) + { + var dispatch_status = Convert.ToByte(pageSearch.sqlTitle.Trim().ToLower().Replace("dispatch_status", "").Replace(":", "").Replace(":", "").Replace("=", "")); + query = query.Where(t => t.dispatch_status.Equals(dispatch_status)); + } + else if (pageSearch.sqlTitle.Equals("to_package")) + { + query = query.Where(t => (t.picked_qty == t.qty && (t.dispatch_status.Equals(3)) || (t.package_qty < t.picked_qty && t.dispatch_status.Equals(5)))); + } + else if (pageSearch.sqlTitle.Equals("to_weight")) + { + query = query.Where(t => t.picked_qty == t.qty && (t.dispatch_status.Equals(3) || (t.weighing_qty < t.picked_qty && t.dispatch_status.Equals(4)))); + } + else if (pageSearch.sqlTitle.Equals("to_delivery")) + { + query = query.Where(t => t.picked_qty == t.qty && (t.dispatch_status.Equals(3) || t.dispatch_status.Equals(4) || t.dispatch_status.Equals(5))); + } + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + /// + /// get dispatchlist by dispatch_no + /// + /// + /// + /// + public async Task> GetByDispatchlistNo(string dispatch_no, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var datas = await (from d in DbSet.AsNoTracking() + join sku in _dBContext.GetDbSet().AsNoTracking() on d.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + where d.dispatch_no == dispatch_no && d.tenant_id == currentUser.tenant_id + select new DispatchlistViewModel + { + id = d.id, + dispatch_no = d.dispatch_no, + dispatch_status = d.dispatch_status, + customer_id = d.customer_id, + customer_name = d.customer_name, + sku_id = d.sku_id, + qty = d.qty, + weight = d.weight, + volume = d.volume, + creator = d.creator, + create_time = d.create_time, + damage_qty = d.damage_qty, + lock_qty = d.lock_qty, + picked_qty = d.picked_qty, + intrasit_qty = d.intrasit_qty, + package_qty = d.package_qty, + unpackage_qty = d.picked_qty - d.package_qty, + weighing_qty = d.weighing_qty, + unweighing_qty = d.picked_qty - d.weighing_qty, + actual_qty = d.actual_qty, + sign_qty = d.sign_qty, + package_no = d.package_no, + package_person = d.package_person, + package_time = d.package_time, + weighing_no = d.weighing_no, + weighing_person = d.weighing_person, + weighing_weight = d.weighing_weight, + waybill_no = d.waybill_no, + carrier = d.carrier, + freightfee = d.freightfee, + last_update_time = d.last_update_time, + tenant_id = d.tenant_id, + sku_code = sku.sku_code, + spu_code = spu.spu_code, + spu_description = spu.spu_description, + spu_name = spu.spu_name, + bar_code = spu.bar_code, + unpicked_qty = d.qty - d.picked_qty + }).ToListAsync(); + return datas; + } + /// + /// update dispatchlist with same dispatch_no + /// + /// + /// + /// + public async Task<(bool flag, string msg)> UpdateAsycn(List viewModels, CurrentUser currentUser) + { + var DBSet = _dBContext.GetDbSet(); + var dispatch_no = viewModels.FirstOrDefault().dispatch_no; + var dispatch_status = viewModels.FirstOrDefault().dispatch_status; + var entities = await (DBSet.Where(t => t.dispatch_no == dispatch_no && t.tenant_id == currentUser.tenant_id)).ToListAsync(); + var delete_id_list = new List(); + var sku_id_list = viewModels.Select(t => t.sku_id).ToList(); + var skus = await (_dBContext.GetDbSet().AsNoTracking().Where(t => sku_id_list.Contains(t.id))).ToListAsync(); + if (entities.Any(t => t.dispatch_status != 1 && t.dispatch_status != 0)) + { + return (false, _stringLocalizer["data_changed"]); + } + foreach (var vm in viewModels) + { + if (vm.id < 0) + { + var entity = entities.FirstOrDefault(t => t.id == -vm.id); + if (entity == null) + { + return (false, _stringLocalizer["data_changed"]); + } + DBSet.Remove(entity); + delete_id_list.Add(entity.id); + } + else if (vm.id > 0) + { + var entity = entities.FirstOrDefault(t => t.id == vm.id); + if (entity == null) + { + return (false, _stringLocalizer["data_changed"]); + } + entity.sku_id = vm.sku_id; + entity.qty = vm.qty; + entity.last_update_time = DateTime.Now; + var sku = skus.FirstOrDefault(t => t.id == entity.sku_id); + if (sku != null) + { + entity.volume = sku.volume * entity.qty; + entity.weight = sku.weight * entity.qty; + } + } + else if (vm.id == 0) + { + var entity = new DispatchlistEntity + { + id = 0, + dispatch_no = dispatch_no, + creator = currentUser.user_name, + create_time = DateTime.Now, + last_update_time = DateTime.Now, + dispatch_status = dispatch_status, + sku_id = vm.sku_id, + qty = vm.qty + + }; + var sku = skus.FirstOrDefault(t => t.id == entity.sku_id); + if (sku != null) + { + entity.volume = sku.volume * entity.qty; + entity.weight = sku.weight * entity.qty; + } + entities.Add(entity); + DBSet.Add(entity); + } + } + var repeat_skus_id_list = entities.Where(t => !delete_id_list.Contains(t.id)).GroupBy(t => t.sku_id).Select(t => new { t.Key, cnt = t.Count() }).Where(t => t.cnt > 1).Select(t => t.Key).ToList(); + if (repeat_skus_id_list.Count > 0) + { + var repeat_skus = (skus.Where(t => repeat_skus_id_list.Contains(t.id)).Select(t => t.sku_code).ToList()); + var msg = ""; + foreach (var sku in repeat_skus) + { + msg += string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["sku_code"], sku); + } + return (false, msg); + } + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// get pick list by dispatch_id + /// + /// dispatch_id + /// + public async Task> GetPickListByDispatchID(int dispatch_id) + { + var datas = await (from dpl in _dBContext.GetDbSet().AsNoTracking() + join sku in _dBContext.GetDbSet().AsNoTracking() on dpl.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + join owner in _dBContext.GetDbSet().AsNoTracking() on dpl.goods_owner_id equals owner.id into o_left + from owner in o_left.DefaultIfEmpty() + join location in _dBContext.GetDbSet().AsNoTracking() on dpl.goods_location_id equals location.id + where dpl.dispatchlist_id == dispatch_id + select new DispatchpicklistViewModel + { + id = dpl.id, + dispatchlist_id = dpl.dispatchlist_id, + goods_owner_id = dpl.goods_owner_id, + goods_location_id = dpl.goods_location_id, + sku_id = dpl.sku_id, + pick_qty = dpl.pick_qty, + picked_qty = dpl.picked_qty, + goods_owner_name = owner.goods_owner_name == null ? "" : owner.goods_owner_name, + sku_code = sku.sku_code, + spu_code = spu.spu_code, + spu_description = spu.spu_description, + spu_name = spu.spu_name, + bar_code = spu.bar_code, + location_name = location.location_name, + warehouse_area_name = location.warehouse_area_name, + warehouse_area_property = location.warehouse_area_property, + warehouse_name = location.warehouse_name, + }).ToListAsync(); + return datas; + } + + /// + /// advanced dispatch order page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> AdvancedDispatchlistPageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet(); + var query = from d in DbSet.AsNoTracking().Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + join sku in _dBContext.GetDbSet().AsNoTracking() on d.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + group new { d, spu } by new { d.dispatch_no, d.dispatch_status, d.customer_id, d.customer_name, d.creator } + into dg + select new PreDispatchlistViewModel + { + dispatch_no = dg.Key.dispatch_no, + dispatch_status = dg.Key.dispatch_status, + customer_id = dg.Key.customer_id, + customer_name = dg.Key.customer_name, + qty = dg.Sum(t => t.d.qty), + volume = dg.Sum(t =>t.spu.volume_unit==1? t.d.volume:(t.spu.volume_unit==0?t.d.volume/1000:t.d.volume*1000)), + weight = dg.Sum(t =>t.spu.weight_unit==0?t.d.weight/1000000:(t.spu.weight_unit==1? t.d.weight/1000:t.d.weight)), + creator = dg.Key.creator, + }; + query = query.Where(queries.AsExpression()); + if (pageSearch.sqlTitle.Contains("dispatch_status")) + { + var dispatch_status = Convert.ToByte(pageSearch.sqlTitle.Trim().ToLower().Replace("dispatch_status", "").Replace(":", "").Replace(":", "").Replace("=", "")); + query = query.Where(t => t.dispatch_status.Equals(dispatch_status)); + } + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.dispatch_no) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + /// + /// Get dispatchlist by dispatch_no + /// + /// + public async Task> GetAllAsync(string dispatch_no, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var Spus = _dBContext.GetDbSet(); + var Skus = _dBContext.GetDbSet(); + var data = await (from dl in DbSet.AsNoTracking() + join sku in Skus.AsNoTracking() on dl.sku_id equals sku.id + join spu in Spus.AsNoTracking() on sku.spu_id equals spu.id + where dl.dispatch_no == dispatch_no && dl.tenant_id == currentUser.tenant_id + select new DispatchlistDetailViewModel + { + id = dl.id, + dispatch_no = dl.dispatch_no, + sku_code = sku.sku_code, + spu_code = spu.spu_code, + spu_description = spu.spu_description, + spu_name = spu.spu_name, + bar_code = spu.bar_code, + dispatch_status = dl.dispatch_status, + customer_id = dl.customer_id, + customer_name = dl.customer_name, + sku_id = dl.sku_id, + qty = dl.qty, + weight = dl.weight, + volume = dl.volume, + creator = dl.creator, + create_time = dl.create_time, + damage_qty = dl.damage_qty, + lock_qty = dl.lock_qty, + picked_qty = dl.picked_qty, + intrasit_qty = dl.intrasit_qty, + package_qty = dl.package_qty, + weighing_qty = dl.weighing_qty, + actual_qty = dl.actual_qty, + sign_qty = dl.sign_qty, + package_no = dl.package_no, + package_person = dl.package_person, + package_time = dl.package_time, + weighing_no = dl.weighing_no, + weighing_person = dl.weighing_person, + weighing_weight = dl.weighing_weight, + waybill_no = dl.waybill_no, + carrier = dl.carrier, + freightfee = dl.freightfee, + } + ).ToListAsync(); + return data.Adapt>(); + } + + /// + /// add a new Dispatchlist + /// + /// viewmodel + /// current user + /// + public async Task<(bool flag, string msg)> AddAsync(List viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var entities = viewModel.Adapt>(); + var sku_id_list = entities.Select(t => t.sku_id).ToList(); + var skus = await _dBContext.GetDbSet().Where(t => sku_id_list.Contains(t.id)).ToListAsync(); + var dispatch_no = await GetOrderCode(currentUser); + foreach (var entity in entities) + { + var sku = skus.FirstOrDefault(t => t.id == entity.sku_id); + entity.id = 0; + entity.create_time = DateTime.Now; + entity.creator = currentUser.user_name; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + if (sku != null) + { + entity.volume = entity.qty * sku.volume; + entity.weight = entity.qty * sku.weight; + } + entity.dispatch_no = dispatch_no; + } + await DbSet.AddRangeAsync(entities); + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + + /// + /// delete a record + /// + /// dispatch_no + /// current user + /// + public async Task<(bool flag, string msg)> DeleteAsync(string dispatch_no, CurrentUser currentUser) + { + var entities = await _dBContext.GetDbSet().Where(t => t.dispatch_no.Equals(dispatch_no) && t.tenant_id == currentUser.tenant_id).ToListAsync(); + if (entities.Any(t => t.dispatch_status > 1)) + { + return (false, _stringLocalizer["status_not_delete"]); + } + _dBContext.GetDbSet().RemoveRange(entities); + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + + /// + /// Dispatchlist details with available stock + /// + /// dispatch_no + /// current user + /// + public async Task> ConfirmOrderCheck(string dispatch_no, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var dispatchpick_DBSet = _dBContext.GetDbSet(); + var stock_DbSet = _dBContext.GetDbSet(); + var asn_DBSet = _dBContext.GetDbSet(); + var dispatch_DBSet = _dBContext.GetDbSet(); + var sku_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var spu_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var processdetail_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var move_DBSet = _dBContext.GetDbSet(); + var owner_DBSet = _dBContext.GetDbSet(); + var location_DBSet = _dBContext.GetDbSet(); + var stock_group_datas = from stock in stock_DbSet.AsNoTracking() + join gl in _dBContext.GetDbSet().AsNoTracking() on stock.goods_location_id equals gl.id + group stock by new { stock.id, stock.sku_id, stock.goods_location_id, stock.goods_owner_id } into sg + select new + { + stock_id = sg.Key.id, + goods_owner_id = sg.Key.goods_owner_id, + sku_id = sg.Key.sku_id, + goods_location_id = sg.Key.goods_location_id, + qty_frozen = sg.Where(t => t.is_freeze == true).Sum(e => e.qty), + qty = sg.Sum(t => t.qty) + }; + var dispatch_group_datas = from dp in DbSet.AsNoTracking() + join dpp in dispatchpick_DBSet.AsNoTracking() on dp.id equals dpp.dispatchlist_id + where dp.dispatch_status > 1 && dp.dispatch_status < 6 + group dpp by new { dpp.sku_id, dpp.goods_location_id, dpp.goods_owner_id } into dg + select new + { + goods_owner_id = dg.Key.goods_owner_id, + sku_id = dg.Key.sku_id, + goods_location_id = dg.Key.goods_location_id, + qty_locked = dg.Sum(t => t.pick_qty) + }; + var process_locked_group_datas = from pd in processdetail_DBSet + where pd.is_update_stock == false + group pd by new { pd.sku_id, pd.goods_location_id, pd.goods_owner_id } into pdg + select new + { + goods_owner_id = pdg.Key.goods_owner_id, + sku_id = pdg.Key.sku_id, + goods_location_id = pdg.Key.goods_location_id, + qty_locked = pdg.Sum(t => t.qty) + }; + var move_locked_group_datas = from m in move_DBSet.AsNoTracking() + where m.move_status == 0 + group m by new { m.sku_id, m.orig_goods_location_id, m.goods_owner_id } into mg + select new + { + goods_owner_id = mg.Key.goods_owner_id, + sku_id = mg.Key.sku_id, + goods_location_id = mg.Key.orig_goods_location_id, + qty_locked = mg.Sum(t => t.qty) + }; + var datas = await (from dl in DbSet + join sg in stock_group_datas on dl.sku_id equals sg.sku_id into sg_left + from sg in sg_left.DefaultIfEmpty() + join dp in dispatch_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { dp.sku_id, dp.goods_location_id, dp.goods_owner_id } into dp_left + from dp in dp_left.DefaultIfEmpty() + join pl in process_locked_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { pl.sku_id, pl.goods_location_id, pl.goods_owner_id } into pl_left + from pl in pl_left.DefaultIfEmpty() + join m in move_locked_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { m.sku_id, m.goods_location_id, m.goods_owner_id } into m_left + from m in m_left.DefaultIfEmpty() + join sku in sku_DBSet on dl.sku_id equals sku.id + join spu in spu_DBSet on sku.spu_id equals spu.id + join owner in owner_DBSet.AsNoTracking() on sg.goods_owner_id equals owner.id into owner_left + from owner in owner_left.DefaultIfEmpty() + join gl in location_DBSet.Where(t=>t.warehouse_area_property != 5).AsNoTracking() on sg.goods_location_id equals gl.id into gl_left + from gl in gl_left.DefaultIfEmpty() + where dl.dispatch_no == dispatch_no && dl.tenant_id == currentUser.tenant_id && (dl.dispatch_status == 0 || dl.dispatch_status == 1) + select new + { + stock_id = sg.stock_id == null ? 0 : sg.stock_id, + goods_owner_name = owner.goods_owner_name == null ? "" : owner.goods_owner_name, + goods_location_id = sg.goods_location_id == null ? 0 : sg.goods_location_id, + goods_owner_id = sg.goods_owner_id == null ? 0 : sg.goods_owner_id, + spu_name = spu.spu_name, + spu_code = spu.spu_code, + sku_code = sku.sku_code, + qty_available = (sg.qty == null ? 0 : sg.qty) - (sg.qty_frozen == null ? 0 : sg.qty_frozen) - (dp.qty_locked == null ? 0 : dp.qty_locked) - (pl.qty_locked == null ? 0 : pl.qty_locked) - (m.qty_locked == null ? 0 : m.qty_locked), + qty = dl.qty, + sku_id = dl.sku_id, + id = dl.id, + spu_description = spu.spu_description, + dispatch_status = dl.dispatch_status, + bar_code = spu.bar_code, + customer_id = dl.customer_id, + customer_name = dl.customer_name, + dispatch_no = dl.dispatch_no, + location_name = gl.location_name == null ? "" : gl.location_name, + warehouse_area_name = gl.warehouse_area_name == null ? "" : gl.warehouse_area_name, + warehouse_name = gl.warehouse_name == null ? "" : gl.warehouse_name + }).ToListAsync(); + var res = (from d in datas + group d by new + { + d.spu_name, + d.spu_code, + d.sku_code, + d.qty, + d.sku_id, + d.id, + d.spu_description, + d.dispatch_status, + d.bar_code, + d.customer_id, + d.customer_name, + d.dispatch_no, + } + into dg + select new DispatchlistConfirmDetailViewModel + { + dispatchlist_id = dg.Key.id, + sku_id = dg.Key.sku_id, + dispatch_no = dg.Key.dispatch_no, + sku_code = dg.Key.sku_code, + spu_code = dg.Key.spu_code, + dispatch_status = dg.Key.dispatch_status, + spu_description = dg.Key.spu_description, + spu_name = dg.Key.spu_name, + bar_code = dg.Key.bar_code, + customer_id = dg.Key.customer_id, + customer_name = dg.Key.customer_name, + qty = dg.Key.qty, + qty_available = dg.Sum(t => t.qty_available), + confirm = dg.Key.qty > dg.Sum(t => t.qty_available) ? false : true + }).ToList(); + foreach (var r in res) + { + var picklist = (from d in datas.Where(t => t.sku_id == r.sku_id && t.stock_id > 0).OrderBy(o => o.qty_available) + select new DispatchlistConfirmPickDetailViewModel + { + stock_id = d.stock_id, + dispatchlist_id = r.dispatchlist_id, + goods_location_id = d.goods_location_id, + qty_available = d.qty_available, + goods_owner_id = d.goods_owner_id, + goods_owner_name = d.goods_owner_name, + location_name = d.location_name, + warehouse_area_name = d.warehouse_area_name, + warehouse_name = d.warehouse_name, + pick_qty = 0 + } + ).OrderByDescending(o => o.qty_available).ToList(); + int pick_qty = 0; + foreach (var pick in picklist) + { + if (pick_qty >= r.qty) + { + break; + } + pick.pick_qty = (r.qty <= (pick_qty + pick.qty_available)) ? (r.qty - pick_qty) : pick.qty_available; + pick_qty += pick.pick_qty; + } + r.pick_list = picklist.Where(t=>t.qty_available>0).ToList(); + } + + return res; + + } + + /// + /// Confirm orders and create dispatchpicklist + /// + /// viewModels + /// current user + /// + public async Task<(bool flag, string msg)> ConfirmOrder(List viewModels, CurrentUser currentUser) + { + var DBSet = _dBContext.GetDbSet(); + var dispatchlist_id_list = viewModels.Select(t => t.dispatchlist_id).ToList(); + var dispatchlist_datas = await DBSet.Where(t => dispatchlist_id_list.Contains(t.id)).ToListAsync(); + var pick_DBSet = _dBContext.GetDbSet(); + var stock_DBSet = _dBContext.GetDbSet(); + var pick_datas = new List(); + var stock_id_list = new List(); + var processdetail_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var move_DBSet = _dBContext.GetDbSet(); + var new_dispatchlists = new List(); + var topick_viewmodels = new List(); + var sku_id_list = viewModels.Select(t => t.sku_id).ToList(); + foreach (var vm in viewModels.Where(t => t.confirm == true).ToList()) + { + stock_id_list.AddRange(vm.pick_list.Where(t => t.pick_qty > 0).Select(t => t.stock_id).ToList()); + } + + foreach (var vm in viewModels) + { + var d = dispatchlist_datas.Where(t => t.id == vm.dispatchlist_id).FirstOrDefault(); + if (d == null) + { + return (false, _stringLocalizer["data_changed"]); + } + if (vm.confirm == true) + { + d.dispatch_status = 2; + d.last_update_time = DateTime.Now; + d.lock_qty = vm.pick_list.Sum(t => t.pick_qty); + foreach (var p in vm.pick_list.Where(t => t.pick_qty > 0).ToList()) + { + pick_datas.Add(new DispatchpicklistEntity + { + sku_id = vm.sku_id, + is_update_stock = false, + dispatchlist_id = p.dispatchlist_id, + goods_location_id = p.goods_location_id, + goods_owner_id = p.goods_owner_id, + last_update_time = DateTime.Now, + pick_qty = p.pick_qty, + }); + topick_viewmodels.Add(new StockViewModel { id = p.stock_id, qty = p.pick_qty }); + } + if (d.lock_qty < d.qty) + { + d.qty = d.lock_qty; + new_dispatchlists.Add(new DispatchlistEntity + { + sku_id = vm.sku_id, + dispatch_status = 1, + qty = d.qty - d.lock_qty, + tenant_id = currentUser.tenant_id + }); + } + } + else + { + new_dispatchlists.Add(new DispatchlistEntity + { + sku_id = vm.sku_id, + dispatch_status = 1, + qty = vm.qty, + tenant_id = currentUser.tenant_id + }); + DBSet.Remove(d); + } + } + var stock_group_datas = from stock in stock_DBSet.AsNoTracking() + where stock_id_list.Contains(stock.id) + group stock by new { stock.id, stock.sku_id, stock.goods_location_id, stock.goods_owner_id } into sg + select new + { + stock_id = sg.Key.id, + goods_owner_id = sg.Key.goods_owner_id, + sku_id = sg.Key.sku_id, + goods_location_id = sg.Key.goods_location_id, + qty_frozen = sg.Where(t => t.is_freeze == true).Sum(e => e.qty), + qty = sg.Sum(t => t.qty) + }; + var dispatch_group_datas = from dp in DBSet.AsNoTracking() + join dpp in pick_DBSet.AsNoTracking() on dp.id equals dpp.dispatchlist_id + where dp.dispatch_status > 1 && dp.dispatch_status < 6 + group dpp by new { dpp.sku_id, dpp.goods_location_id, dpp.goods_owner_id } into dg + select new + { + goods_owner_id = dg.Key.goods_owner_id, + sku_id = dg.Key.sku_id, + goods_location_id = dg.Key.goods_location_id, + qty_locked = dg.Sum(t => t.pick_qty) + }; + var process_locked_group_datas = from pd in processdetail_DBSet + where pd.is_update_stock == false + group pd by new { pd.sku_id, pd.goods_location_id, pd.goods_owner_id } into pdg + select new + { + goods_owner_id = pdg.Key.goods_owner_id, + sku_id = pdg.Key.sku_id, + goods_location_id = pdg.Key.goods_location_id, + qty_locked = pdg.Sum(t => t.qty) + }; + var move_locked_group_datas = from m in move_DBSet.AsNoTracking() + where m.move_status == 0 + group m by new { m.sku_id, m.orig_goods_location_id, m.goods_owner_id } into mg + select new + { + goods_owner_id = mg.Key.goods_owner_id, + sku_id = mg.Key.sku_id, + goods_location_id = mg.Key.orig_goods_location_id, + qty_locked = mg.Sum(t => t.qty) + }; + var stock_datas = await (from sg in stock_group_datas + join dp in dispatch_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { dp.sku_id, dp.goods_location_id, dp.goods_owner_id } into dp_left + from dp in dp_left.DefaultIfEmpty() + join pl in process_locked_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { pl.sku_id, pl.goods_location_id, pl.goods_owner_id } into pl_left + from pl in pl_left.DefaultIfEmpty() + join m in move_locked_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { m.sku_id, m.goods_location_id, m.goods_owner_id } into m_left + from m in m_left.DefaultIfEmpty() + select new + { + stock_id = sg.stock_id, + qty_available = (sg.qty == null ? 0 : sg.qty) - (sg.qty_frozen == null ? 0 : sg.qty_frozen) - (dp.qty_locked == null ? 0 : dp.qty_locked) - (pl.qty_locked == null ? 0 : pl.qty_locked) - (m.qty_locked == null ? 0 : m.qty_locked), + }).ToListAsync(); + var if_not_stock = (from tp in topick_viewmodels + join s in stock_datas on tp.id equals s.stock_id + where tp.qty > s.qty_available + select tp).Any(); + if (if_not_stock) + { + return (false, _stringLocalizer["data_changed"]); + } + await pick_DBSet.AddRangeAsync(pick_datas); + var dispatch_no = await GetOrderCode(currentUser); + var sku_datas = await _dBContext.GetDbSet().Where(t => sku_id_list.Contains(t.id)).ToListAsync(); + foreach (var nd in new_dispatchlists) + { + nd.dispatch_no = dispatch_no; + nd.creator = currentUser.user_name; + nd.create_time = DateTime.Now; + var sku = sku_datas.FirstOrDefault(e => e.id == nd.sku_id); + if (sku != null) + { + nd.weight = nd.qty * sku.weight; + nd.volume = nd.qty * sku.volume; + } + }; + await DBSet.AddRangeAsync(new_dispatchlists); + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + else + { + return (false, _stringLocalizer["operation_failed"]); + } + } + + /// + /// cancel order opration + /// + /// viewmodel + /// current user + /// + public async Task<(bool flag, string msg)> CancelOrderOpration(CancelOrderOprationViewModel viewModel, CurrentUser currentUser) + { + var DBSet = _dBContext.GetDbSet(); + var pick_DBSet = _dBContext.GetDbSet(); + var entities = await DBSet.Where(t => t.dispatch_no == viewModel.dispatch_no && t.tenant_id == currentUser.tenant_id && t.dispatch_status == viewModel.dispatch_status).ToListAsync(); + if (entities.Count == 0) + { + return (false, _stringLocalizer["status_changed"]); + } + var time = DateTime.Now; + var dispatch_id_list = entities.Select(t => t.id).ToList(); + var pick_entities = await pick_DBSet.Where(t => dispatch_id_list.Contains(t.dispatchlist_id)).ToListAsync(); + if (viewModel.dispatch_status == 3) + { + foreach (var pick in pick_entities) + { + pick.picked_qty = 0; + pick.last_update_time = time; + } + foreach (var entity in entities) + { + entity.picked_qty = 0; + entity.last_update_time = time; + entity.dispatch_status = 2; + } + } + else if (viewModel.dispatch_status == 2) + { + pick_DBSet.RemoveRange(pick_entities); + foreach (var entity in entities) + { + entity.lock_qty = 0; + entity.last_update_time = time; + entity.dispatch_status = 1; + } + } + var saved = false; + int res = 0; + while (!saved) + { + try + { + // Attempt to save changes to the database + res = await _dBContext.SaveChangesAsync(); + saved = true; + } + catch (DbUpdateConcurrencyException ex) + { + foreach (var entry in ex.Entries) + { + if (entry.Entity is DispatchlistEntity) + { + var proposedValues = entry.CurrentValues; + var databaseValues = entry.GetDatabaseValues(); + if (UtilConvert.ObjToInt(databaseValues["dispatch_status"]) != viewModel.dispatch_status) + return (false, _stringLocalizer["data_changed"]); + // Refresh original values to bypass next concurrency check + entry.OriginalValues.SetValues(databaseValues); + } + else + { + throw new NotSupportedException(_stringLocalizer["try_agin"]); + } + } + } + } + if (res > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + else + { + return (false, _stringLocalizer["operation_failed"]); + } + } + + /// + /// cancel dispatchlist detail opration + /// + /// dispatchlist_id + /// + public async Task<(bool flag, string msg)> CancelDispatchlistDetailOpration(int id) + { + var DBSet = _dBContext.GetDbSet(); + var entity = await DBSet.Where(t => t.id == id).FirstOrDefaultAsync(); + var time = DateTime.Now; + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + if (entity.dispatch_status == 4) + { + if (entity.weighing_no == "") + { + entity.dispatch_status = 3; + } + else + { + entity.dispatch_status = 5; + } + entity.package_no = ""; + entity.package_qty = 0; + entity.package_time = UtilConvert.MinDate; + entity.package_person = ""; + } + else if (entity.dispatch_status == 5) + { + if (entity.package_no == "") + { + entity.dispatch_status = 3; + } + else + { + entity.dispatch_status = 4; + } + entity.weighing_no = ""; + entity.weighing_qty = 0; + entity.weighing_weight = 0; + entity.weighing_person = ""; + } + else + { + return (false, _stringLocalizer["status_changed"]); + } + entity.last_update_time = time; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + else + { + return (false, _stringLocalizer["operation_failed"]); + } + } + + /// + /// confirm dispatchpicklist picked by dispatch_no + /// + /// dispatch_no + /// current user + /// + public async Task<(bool flag, string msg)> ConfirmPickByDispatchNo(string dispatch_no, CurrentUser currentUser) + { + var DBSet = _dBContext.GetDbSet(); + var pick_DBSet = _dBContext.GetDbSet(); + var entities = await DBSet.Where(t => t.dispatch_status == 2 && t.dispatch_no == dispatch_no && t.tenant_id == currentUser.tenant_id).ToListAsync(); + var dispatchlist_id_list = entities.Select(t => t.id).ToList(); + var pick_datas = await pick_DBSet.Where(t => dispatchlist_id_list.Contains(t.dispatchlist_id)).ToListAsync(); + entities.ForEach(t => + { + t.picked_qty = t.lock_qty; + t.dispatch_status = 3; + t.last_update_time = DateTime.Now; + }); + pick_datas.ForEach(t => + { + t.picked_qty = t.pick_qty; + t.last_update_time = DateTime.Now; + }); + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + else + { + return (false, _stringLocalizer["operation_failed"]); + } + } + + /// + /// package + /// + /// viewModels + /// currentUser + /// + /// + public async Task<(bool flag, string msg)> Package(List viewModels, CurrentUser currentUser) + { + var DBSet = _dBContext.GetDbSet(); + var dispatchlist_id_list = viewModels.Select(t => t.id).ToList(); + var entities = await DBSet.Where(t => dispatchlist_id_list.Contains(t.id)).ToListAsync(); + var time = DateTime.Now; + var code = GetPackageOrWeightCode(); + foreach (var vm in viewModels) + { + var entity = entities.FirstOrDefault(t => t.id == vm.id && t.dispatch_status == vm.dispatch_status); + if (entity == null) + { + return (false, _stringLocalizer["data_changed"]); + } + if ((entity.package_qty + vm.package_qty) > entity.picked_qty) + { + return (false, _stringLocalizer["unpackgeqty_lessthen"]); + } + entity.last_update_time = time; + entity.package_person = currentUser.user_name; + entity.package_qty += vm.package_qty; + entity.package_time = time; + entity.package_no = code; + entity.dispatch_status = 4; + } + var saved = false; + int res = 0; + while (!saved) + { + try + { + // Attempt to save changes to the database + res = await _dBContext.SaveChangesAsync(); + saved = true; + } + catch (DbUpdateConcurrencyException ex) + { + foreach (var entry in ex.Entries) + { + if (entry.Entity is DispatchlistEntity) + { + var proposedValues = entry.CurrentValues; + var databaseValues = entry.GetDatabaseValues(); + var t_vm = viewModels.FirstOrDefault(t => t.id == UtilConvert.ObjToInt(databaseValues["id"])); + if (t_vm == null) + { + return (false, _stringLocalizer["data_changed"]); + } + if (UtilConvert.ObjToInt(databaseValues["package_qty"]) + t_vm.package_qty > t_vm.picked_qty) + { + return (false, _stringLocalizer["data_changed"]); + } + else + { + proposedValues["package_qty"] = UtilConvert.ObjToInt(databaseValues["package_qty"]) + t_vm.package_qty; + proposedValues["last_update_time"] = DateTime.Now; + if (UtilConvert.ObjToInt(databaseValues["package_qty"]) + t_vm.package_qty == UtilConvert.ObjToInt(databaseValues["picked_qty"])) + { + proposedValues["dispatch_status"] = 4; + } + } + // Refresh original values to bypass next concurrency check + entry.OriginalValues.SetValues(databaseValues); + } + else + { + throw new NotSupportedException(_stringLocalizer["try_agin"]); + } + } + } + } + if (res > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + else + { + return (false, _stringLocalizer["operation_failed"]); + } + } + + /// + /// weight + /// + /// viewModels + /// currentUser + /// + /// + public async Task<(bool flag, string msg)> Weight(List viewModels, CurrentUser currentUser) + { + var DBSet = _dBContext.GetDbSet(); + var dispatchlist_id_list = viewModels.Select(t => t.id).ToList(); + var entities = await DBSet.Where(t => dispatchlist_id_list.Contains(t.id)).ToListAsync(); + var time = DateTime.Now; + var code = GetPackageOrWeightCode(); + foreach (var vm in viewModels) + { + var entity = entities.FirstOrDefault(t => t.id == vm.id && t.dispatch_status == vm.dispatch_status); + if (entity == null) + { + return (false, _stringLocalizer["data_changed"]); + } + if ((entity.weighing_qty + vm.weighing_qty) > entity.picked_qty) + { + return (false, _stringLocalizer["unweightqty_lessthen"]); + } + entity.last_update_time = time; + entity.weighing_person = currentUser.user_name; + entity.weighing_qty += vm.weighing_qty; + entity.weighing_weight += vm.weighing_weight; + entity.weighing_no = code; + entity.dispatch_status = 5; + } + var saved = false; + int res = 0; + while (!saved) + { + try + { + // Attempt to save changes to the database + res = await _dBContext.SaveChangesAsync(); + saved = true; + } + catch (DbUpdateConcurrencyException ex) + { + foreach (var entry in ex.Entries) + { + if (entry.Entity is StockEntity) + { + var proposedValues = entry.CurrentValues; + var databaseValues = entry.GetDatabaseValues(); + + var t_vm = viewModels.FirstOrDefault(t => t.id == UtilConvert.ObjToInt(databaseValues["id"])); + if (t_vm == null) + { + return (false, _stringLocalizer["data_changed"]); + } + if (UtilConvert.ObjToInt(databaseValues["weighing_qty"]) + t_vm.weighing_qty > t_vm.picked_qty) + { + return (false, _stringLocalizer["data_changed"]); + } + else + { + proposedValues["weighing_qty"] = UtilConvert.ObjToInt(databaseValues["weighing_qty"]) + t_vm.weighing_qty; + proposedValues["weighing_weight"] = UtilConvert.ObjToInt(databaseValues["weighing_weight"]) + t_vm.weighing_weight; + if (UtilConvert.ObjToInt(databaseValues["weighing_qty"]) + t_vm.weighing_qty == UtilConvert.ObjToInt(databaseValues["picked_qty"])) + { + proposedValues["dispatch_status"] = 5; + } + proposedValues["last_update_time"] = DateTime.Now; + } + // Refresh original values to bypass next concurrency check + entry.OriginalValues.SetValues(databaseValues); + } + else + { + throw new NotSupportedException(_stringLocalizer["try_agin"]); + } + } + } + } + if (res > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + else + { + return (false, _stringLocalizer["operation_failed"]); + } + } + + /// + /// dispatchpicklist outbound delivery + /// + /// viewModels + /// currentUser + /// + /// + public async Task<(bool flag, string msg)> Delivery(List viewModels, CurrentUser currentUser) + { + var DBSet = _dBContext.GetDbSet(); + var dispatchlist_id_list = viewModels.Select(t => t.id).ToList(); + var pick_DBSet = _dBContext.GetDbSet(); + var stock_DBSet = _dBContext.GetDbSet(); + var entities = await DBSet.Where(t => dispatchlist_id_list.Contains(t.id)).ToListAsync(); + var time = DateTime.Now; + foreach (var entity in entities) + { + if (entity.dispatch_status != 3 && entity.dispatch_status != 4 && entity.dispatch_status != 5) + { + return (false, _stringLocalizer["data_changed"]); + } + entity.last_update_time = time; + entity.dispatch_status = 6; + entity.lock_qty = 0; + entity.actual_qty = entity.picked_qty; + entity.intrasit_qty = entity.picked_qty; + } + var pick_sql = pick_DBSet.Where(t => dispatchlist_id_list.Contains(t.dispatchlist_id)); + var pick_datas = await pick_sql.ToListAsync(); + var picks_g = pick_sql.AsNoTracking().GroupBy(e => new { e.goods_location_id, e.sku_id, e.goods_owner_id }).Select(c => new { c.Key.goods_location_id, c.Key.sku_id, c.Key.goods_owner_id, picked_qty = c.Sum(t => t.picked_qty) }); + var picks = await picks_g.ToListAsync(); + var stocks = await (from stock in stock_DBSet + where picks_g.Any(t => t.goods_location_id == stock.goods_location_id && t.sku_id == stock.sku_id && t.goods_owner_id == stock.goods_owner_id) + select stock).ToListAsync(); + foreach (var pick in picks) + { + var s = stocks.FirstOrDefault(t => t.goods_location_id == pick.goods_location_id && t.sku_id == pick.sku_id && t.goods_owner_id == pick.goods_owner_id); + if (s == null) + { + return (false, _stringLocalizer["data_changed"]); + } + s.qty -= pick.picked_qty; + s.last_update_time = time; + stock_DBSet.Update(s); + } + foreach (var pick in pick_datas) + { + pick.is_update_stock = true; + pick.last_update_time = DateTime.Now; + } + var saved = false; + int res = 0; + while (!saved) + { + try + { + // Attempt to save changes to the database + res = await _dBContext.SaveChangesAsync(); + saved = true; + } + catch (DbUpdateConcurrencyException ex) + { + foreach (var entry in ex.Entries) + { + if (entry.Entity is DispatchlistEntity) + { + var proposedValues = entry.CurrentValues; + var databaseValues = entry.GetDatabaseValues(); + if (UtilConvert.ObjToInt(databaseValues["dispatch_status"]) != 3 && UtilConvert.ObjToInt(databaseValues["dispatch_status"]) != 4 && UtilConvert.ObjToInt(databaseValues["dispatch_status"]) != 5) + { + return (false, _stringLocalizer["data_changed"]); + } + proposedValues["last_update_time"] = DateTime.Now; + } + else if (entry.Entity is StockEntity) + { + var proposedValues = entry.CurrentValues; + var databaseValues = entry.GetDatabaseValues(); + var t_p = picks.FirstOrDefault(t => t.goods_location_id == UtilConvert.ObjToInt(databaseValues["goods_location_id"]) && t.sku_id == UtilConvert.ObjToInt(databaseValues["sku_id"]) && t.goods_owner_id == UtilConvert.ObjToInt(databaseValues["goods_owner_id"])); + if (t_p == null) + { + return (false, _stringLocalizer["data_changed"]); + } + proposedValues["qty"] = UtilConvert.ObjToInt(databaseValues["qty"]) - t_p.picked_qty; + proposedValues["last_update_time"] = DateTime.Now; + // Refresh original values to bypass next concurrency check + entry.OriginalValues.SetValues(databaseValues); + } + else + { + throw new NotSupportedException(_stringLocalizer["try_agin"]); + } + } + } + } + if (res > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + else + { + return (false, _stringLocalizer["operation_failed"]); + } + } + /// + /// set dispatchlist freightfee + /// + /// + /// + public async Task<(bool flag, string msg)> SetFreightfee(List viewModels) + { + var DBSet = _dBContext.GetDbSet(); + var dispatchlist_id_list = viewModels.Select(t => t.id).ToList(); + var freightfee_id_list = viewModels.Select(t => t.freightfee_id).Distinct().ToList(); + var entities = await DBSet.Where(t => dispatchlist_id_list.Contains(t.id)).ToListAsync(); + var freightfees = await _dBContext.GetDbSet().Where(t => freightfee_id_list.Contains(t.id)).ToListAsync(); + var time = DateTime.Now; + foreach (var entity in entities) + { + var vm = viewModels.FirstOrDefault(t => t.id == entity.id); + if (vm != null) + { + var freightfee = freightfees.FirstOrDefault(t => t.id == vm.freightfee_id); + if (freightfee != null) + { + entity.last_update_time = time; + entity.carrier = freightfee.carrier; + entity.waybill_no = vm.waybill_no; + if (entity.weighing_no != "") + { + entity.freightfee = entity.weighing_weight * freightfee.price_per_weight > freightfee.min_payment ? entity.weighing_weight * freightfee.price_per_weight : freightfee.min_payment; + } + else + { + entity.freightfee = Math.Max(Math.Max(entity.weight * freightfee.price_per_weight, entity.volume * freightfee.price_per_volume), freightfee.min_payment); + } + } + } + } + var res = await _dBContext.SaveChangesAsync(); + if (res > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + else + { + return (false, _stringLocalizer["operation_failed"]); + } + } + /// + /// sign for arrival + /// + /// viewModels + /// + public async Task<(bool flag, string msg)> SignForArrival(List viewModels) + { + var DBSet = _dBContext.GetDbSet(); + var dispatchlist_id_list = viewModels.Select(t => t.id).ToList(); + var entities = await DBSet.Where(t => dispatchlist_id_list.Contains(t.id)).ToListAsync(); + foreach (var entity in entities) + { + var vm = viewModels.FirstOrDefault(t => t.id == t.id && t.dispatch_status == entity.dispatch_status); + if (vm == null) + { + return (false, _stringLocalizer["data_changed"]); + } + entity.sign_qty = entity.actual_qty - vm.damage_qty; + entity.damage_qty = vm.damage_qty; + entity.last_update_time = DateTime.Now; + entity.dispatch_status = 7; + } + var res = await _dBContext.SaveChangesAsync(); + if (res > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + else + { + return (false, _stringLocalizer["operation_failed"]); + } + } + /// + /// get next order code number + /// + /// + public async Task GetOrderCode(CurrentUser currentUser) + { + string code; + string date = DateTime.Now.ToString("yyyy" + "MM" + "dd"); + string maxNo = await _dBContext.GetDbSet().Where(t => t.tenant_id == currentUser.tenant_id).MaxAsync(t => t.dispatch_no); + if (maxNo == null) + { + code = date + "-0001"; + } + else + { + string maxDate = maxNo.Substring(0, 8); + string maxDateNo = maxNo.Substring(9, 4); + if (date == maxDate) + { + int.TryParse(maxDateNo, out int dd); + int newDateNo = dd + 1; + code = date + "-" + newDateNo.ToString("0000"); + } + else + { + code = date + "-0001"; + } + } + + return code; + } + + /// + /// get package or weight code + /// + /// + public string GetPackageOrWeightCode() + { + string date = DateTime.Now.ToString("yyyy" + "MM" + "dd"); + DateTime _dtStart = new DateTime(1970, 1, 1, 8, 0, 0); + long timeStamp = Convert.ToInt32(DateTime.Now.Subtract(_dtStart).TotalSeconds); + return date + timeStamp.ToString(); + } + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/Services/Freightfee/FreightfeeService.cs b/backend/ModernWMS.WMS/Services/Freightfee/FreightfeeService.cs new file mode 100644 index 0000000..e8974b0 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Freightfee/FreightfeeService.cs @@ -0,0 +1,233 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ +using Mapster; +using Microsoft.EntityFrameworkCore; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using ModernWMS.Core.Models; +using ModernWMS.Core.JWT; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DynamicSearch; +using System.Text; + +namespace ModernWMS.WMS.Services +{ + /// + /// Freightfee Service + /// + public class FreightfeeService : BaseService, IFreightfeeService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Freightfee constructor + /// + /// The DBContext + /// Localizer + public FreightfeeService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet(); + var query = DbSet.AsNoTracking() + .Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + .Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list.Adapt>(), totals); + } + + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking().Where(t => t.tenant_id.Equals(currentUser.tenant_id)).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.AsNoTracking().FirstOrDefaultAsync(t => t.id.Equals(id)); + if (entity == null) + { + return null; + } + return entity.Adapt(); + } + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + public async Task<(int id, string msg)> AddAsync(FreightfeeViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var entity = viewModel.Adapt(); + entity.id = 0; + entity.create_time = DateTime.Now; + entity.creator = currentUser.user_name; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// + public async Task<(bool flag, string msg)> UpdateAsync(FreightfeeViewModel viewModel) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + entity.id = viewModel.id; + entity.carrier = viewModel.carrier; + entity.departure_city = viewModel.departure_city; + entity.arrival_city = viewModel.arrival_city; + entity.price_per_weight = viewModel.price_per_weight; + entity.price_per_volume = viewModel.price_per_volume; + entity.min_payment = viewModel.min_payment; + entity.is_valid = viewModel.is_valid; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + + /// + /// import freightfee by excel + /// + /// excel datas + /// current user + /// + public async Task<(bool flag, string msg)> ExcelAsync(List datas, CurrentUser currentUser) + { + StringBuilder sb = new StringBuilder(); + var DbSet = _dBContext.GetDbSet(); + /* var user_num_repeat_excel = datas.GroupBy(t => t.warehouse_name).Select(t => new { warehouse_name = t.Key, cnt = t.Count() }).Where(t => t.cnt > 1).ToList(); + foreach (var repeat in user_num_repeat_excel) + { + sb.AppendLine(string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["warehouse_name"], repeat.warehouse_name)); + } + if (user_num_repeat_excel.Count > 1) + { + return (false, sb.ToString()); + } + + var user_num_repeat_exists = await DbSet.Where(t => datas.Select(t => t.warehouse_name).ToList().Contains(t.warehouse_name)).Select(t => t.warehouse_name).ToListAsync(); + foreach (var repeat in user_num_repeat_exists) + { + sb.AppendLine(string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["warehouse_name"], repeat)); + } + if (user_num_repeat_exists.Count > 1) + { + return (false, sb.ToString()); + }*/ + + var entities = datas.Adapt>(); + entities.ForEach(t => + { + t.creator = currentUser.user_name; + t.tenant_id = currentUser.tenant_id; + t.create_time = DateTime.Now; + t.last_update_time = DateTime.Now; + t.is_valid = true; + }); + await DbSet.AddRangeAsync(entities); + var res = await _dBContext.SaveChangesAsync(); + if (res > 0) + { + return (true, _stringLocalizer["save_success"]); + } + return (false, _stringLocalizer["save_failed"]); + } + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/Services/GoodsOwner/GoodsownerService.cs b/backend/ModernWMS.WMS/Services/GoodsOwner/GoodsownerService.cs new file mode 100644 index 0000000..7dcc404 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/GoodsOwner/GoodsownerService.cs @@ -0,0 +1,242 @@ +using Mapster; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.DynamicSearch; +using ModernWMS.Core.JWT; +using ModernWMS.Core.Models; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; + +namespace ModernWMS.WMS.Services +{ + /// + /// Goods owner Service + /// + public class GoodsownerService : BaseService, IGoodsownerService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localization + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// company service constructor + /// + /// The DBContext + /// Localization + public GoodsownerService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet(); + var query = DbSet.AsNoTracking() + .Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + .Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list.Adapt>(), totals); + } + /// + /// Get all records + /// + /// currentUser + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking().Where(t => t.tenant_id == currentUser.tenant_id) + .OrderByDescending(t => t.create_time).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// id + /// + public async Task GetAsync(int id) + { + var entity = await _dBContext.GetDbSet().AsNoTracking().FirstOrDefaultAsync(t => t.id.Equals(id)); + if (entity != null) + { + return entity.Adapt(); + } + else + { + return new GoodsownerViewModel(); + } + } + /// + /// add a new record + /// + /// args + /// currentUser + /// + public async Task<(int id, string msg)> AddAsync(GoodsownerViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.tenant_id.Equals(currentUser.tenant_id) && t.goods_owner_name.Equals(viewModel.goods_owner_name))) + { + return (0, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["goods_owner_name"], viewModel.goods_owner_name)); + } + var entity = viewModel.Adapt(); + entity.id = 0; + entity.creator = currentUser.user_name; + entity.create_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// + public async Task<(bool flag, string msg)> UpdateAsync(GoodsownerViewModel viewModel) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + if (await DbSet.AnyAsync(t => !t.id.Equals(viewModel.id) && t.tenant_id.Equals(entity.tenant_id) && t.goods_owner_name.Equals(viewModel.goods_owner_name))) + { + return (false, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["goods_owner_name"], viewModel.goods_owner_name)); + } + entity.goods_owner_name = viewModel.goods_owner_name; + entity.city = viewModel.city; + entity.address = viewModel.address; + entity.manager = viewModel.manager; + entity.contact_tel = viewModel.contact_tel; + entity.is_valid = viewModel.is_valid; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + #endregion + + + #region Import + /// + /// import goodsowners by excel + /// + /// excel data + /// currentUser + /// + public async Task<(bool flag, List errorData)> ExcelAsync(List input, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var existsDatas = await DbSet.AsNoTracking().Where(t => t.tenant_id.Equals(currentUser.tenant_id)).Select(t => new { t.goods_owner_name }).ToListAsync(); + input.ForEach(async t => + { + t.errorMsg = string.Empty; + if (existsDatas.Any(d => d.goods_owner_name.Equals(t.goods_owner_name))) + { + t.errorMsg = string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["goods_owner_name"], t.goods_owner_name); + } + else + { + await DbSet.AddAsync(new GoodsownerEntity + { + goods_owner_name = t.goods_owner_name, + city = t.city, + address = t.address, + manager = t.manager, + contact_tel = t.contact_tel, + creator = currentUser.user_name, + create_time = DateTime.Now, + last_update_time = DateTime.Now, + is_valid = true, + tenant_id = currentUser.tenant_id + }); + } + }); + if (input.Any(t => t.errorMsg.Length > 0)) + { + return (false, input.Where(t => t.errorMsg.Length > 0).ToList()); + } + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, new List()); + } + else + { + return (false, new List()); + } + } + + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Services/Goodslocation/GoodslocationService.cs b/backend/ModernWMS.WMS/Services/Goodslocation/GoodslocationService.cs new file mode 100644 index 0000000..645de9b --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Goodslocation/GoodslocationService.cs @@ -0,0 +1,228 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ + using Mapster; + using Microsoft.EntityFrameworkCore; + using ModernWMS.Core.DBContext; + using ModernWMS.Core.Services; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using ModernWMS.Core.Models; + using ModernWMS.Core.JWT; + using Microsoft.Extensions.Localization; + using ModernWMS.Core.DynamicSearch; + + namespace ModernWMS.WMS.Services + { + /// + /// Goodslocation Service + /// + public class GoodslocationService : BaseService, IGoodslocationService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Goodslocation constructor + /// + /// The DBContext + /// Localizer + public GoodslocationService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// get goodslocation of the warehousearea by warehouse_id and warehousearea_id + /// + /// warehousearea's id + /// current user + /// + public async Task> GetGoodslocationByWarehouse_area_id( int warehouse_area_id, CurrentUser currentUser) + { + var res = new List(); + var DbSet = _dBContext.GetDbSet(); + res = await (from g in DbSet.AsNoTracking() + where g.is_valid == true && g.tenant_id == currentUser.tenant_id && g.warehouse_area_id== warehouse_area_id + select new FormSelectItem + { + code = "goodslocation", + comments = "goodslocations of the warehousearea", + name = g.location_name, + value = g.id.ToString(), + }).ToListAsync(); + return res; + } + + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet().AsNoTracking(); + + var query = DbSet + .Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + .Where(queries.AsExpression()); + if (pageSearch.sqlTitle == "select") + { + query = query.Where(t => t.is_valid == true); + } + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list.Adapt>(), totals); + } + + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking().Where(t=>t.tenant_id.Equals(currentUser.tenant_id)).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.AsNoTracking().FirstOrDefaultAsync(t=>t.id.Equals(id)); + if (entity == null) + { + return null; + } + return entity.Adapt(); + } + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + public async Task<(int id, string msg)> AddAsync(GoodslocationViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.location_name == viewModel.location_name && t.tenant_id == currentUser.tenant_id)) + { + return (0, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["location_name"], viewModel.location_name)); + } + var entity = viewModel.Adapt(); + entity.id = 0; + entity.create_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// currentUser + /// + public async Task<(bool flag, string msg)> UpdateAsync(GoodslocationViewModel viewModel,CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.id != viewModel.id && t.warehouse_id == viewModel.warehouse_id && t.location_name == viewModel.location_name && t.tenant_id == currentUser.tenant_id)) + { + return (false, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["location_name"], viewModel.location_name)); + } + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false,_stringLocalizer[ "not_exists_entity"]); + } + entity.id = viewModel.id; + entity.warehouse_id = viewModel.warehouse_id; + entity.warehouse_name = viewModel.warehouse_name; + entity.warehouse_area_name = viewModel.warehouse_area_name; + entity.warehouse_area_property = viewModel.warehouse_area_property; + entity.location_name = viewModel.location_name; + entity.location_length = viewModel.location_length; + entity.location_width = viewModel.location_width; + entity.location_heigth = viewModel.location_heigth; + entity.location_volume = viewModel.location_volume; + entity.location_load = viewModel.location_load; + entity.roadway_number = viewModel.roadway_number; + entity.shelf_number = viewModel.shelf_number; + entity.layer_number = viewModel.layer_number; + entity.tag_number = viewModel.tag_number; + entity.is_valid = viewModel.is_valid; + entity.warehouse_area_id = viewModel.warehouse_area_id; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/Services/Rolemenu/RolemenuService.cs b/backend/ModernWMS.WMS/Services/Rolemenu/RolemenuService.cs new file mode 100644 index 0000000..e2fb75c --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Rolemenu/RolemenuService.cs @@ -0,0 +1,281 @@ +/* + * date:2022-12-20 + * developer:AMo + */ +using Mapster; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.JWT; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using ModernWMS.Core.Models; +namespace ModernWMS.WMS.Services +{ + /// + /// Rolemenu Service + /// + public class RolemenuService : BaseService, IRolemenuService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Rolemenu constructor + /// + /// The DBContext + /// Localizer + public RolemenuService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// Get all records + /// + /// currentUser + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var Rolemenus = _dBContext.GetDbSet(); + var Userroles = _dBContext.GetDbSet(); + var queryMenusGroup = Rolemenus.AsNoTracking() + .Where(t => t.tenant_id == currentUser.tenant_id) + .GroupBy(g => new { g.userrole_id }) + .Select(g => new + { + userrole_id = g.Key.userrole_id, + create_time = g.Min(t => t.create_time), + last_update_time = g.Max(t => t.last_update_time) + }); + var data = await (from g in queryMenusGroup + join r in Userroles.AsNoTracking().Where(t => t.tenant_id == currentUser.tenant_id) + on g.userrole_id equals r.id + select new RolemenuListViewModel + { + userrole_id = g.userrole_id, + role_name = r.role_name, + is_valid = r.is_valid, + create_time = g.create_time, + last_update_time = g.last_update_time + }).ToListAsync(); + return data; + } + + /// + /// Get a record by id + /// + /// userrole id + /// + public async Task GetAsync(int userrole_id) + { + var Rolemenus = _dBContext.GetDbSet(); + var Userroles = _dBContext.GetDbSet(); + var Menus = _dBContext.GetDbSet(); + var entities = await (from rm in Rolemenus.AsNoTracking() + join m in Menus.AsNoTracking() on rm.menu_id equals m.id + join r in Userroles.AsNoTracking() on rm.userrole_id equals r.id + where rm.userrole_id == userrole_id + orderby r.role_name, m.sort, m.menu_name + select new + { + rm.id, + rm.userrole_id, + r.role_name, + r.is_valid, + rm.menu_id, + m.menu_name, + rm.authority, + rm.create_time, + rm.last_update_time + }).ToListAsync(); + if (entities.Any()) + { + var data = new RolemenuBothViewModel + { + userrole_id = entities.First().userrole_id, + role_name = entities.First().role_name, + is_valid = entities.First().is_valid, + detailList = entities.Adapt>() + }; + return data; + } + else + { + return new RolemenuBothViewModel(); + } + } + /// + /// Get all menus + /// + /// currentUser + /// + public async Task> GetAllMenusAsync(CurrentUser currentUser) + { + var Menus = _dBContext.GetDbSet(); + var data = await Menus.AsNoTracking() + .Where(t => t.tenant_id == currentUser.tenant_id) + .Select(m => new MenuViewModel + { + id = m.id, + menu_name = m.menu_name, + module = m.module, + vue_path = m.vue_path, + vue_path_detail = m.vue_path_detail, + vue_directory = m.vue_directory, + sort = m.sort + }).ToListAsync(); + return data; + } + /// + /// Get menu's authority by user role id + /// + /// user role id + /// + public async Task> GetMenusByRoleId(int userrole_id) + { + var Rolemenus = _dBContext.GetDbSet(); + var Menus = _dBContext.GetDbSet(); + var data = await (from rm in Rolemenus.AsNoTracking() + join m in Menus.AsNoTracking() on rm.menu_id equals m.id + where rm.userrole_id == userrole_id + orderby m.sort, m.menu_name + select new MenuViewModel + { + id = m.id, + menu_name = m.menu_name, + module = m.module, + vue_path = m.vue_path, + vue_path_detail = m.vue_path_detail, + vue_directory = m.vue_directory, + sort = m.sort + }).ToListAsync(); + return data; + } + /// + /// add a new record + /// + /// viewmodel + /// currentUser + /// + public async Task<(int id, string msg)> AddAsync(RolemenuBothViewModel viewModel, CurrentUser currentUser) + { + var Rolemenus = _dBContext.GetDbSet(); + if (await Rolemenus.AnyAsync(t => t.userrole_id.Equals(viewModel.userrole_id))) + { + return (0, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["role_name"], viewModel.role_name)); + } + var entities = viewModel.detailList.Select(t => new RolemenuEntity + { + id = 0, + userrole_id = viewModel.userrole_id, + menu_id = t.menu_id, + authority = t.authority, + create_time = DateTime.Now, + last_update_time = DateTime.Now, + tenant_id = currentUser.tenant_id + }).ToList(); + + await Rolemenus.AddRangeAsync(entities); + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (viewModel.userrole_id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// currentUser + /// + public async Task<(bool flag, string msg)> UpdateAsync(RolemenuBothViewModel viewModel, CurrentUser currentUser) + { + var Rolemenus = _dBContext.GetDbSet(); + if (!(await Rolemenus.AnyAsync(t => t.userrole_id.Equals(viewModel.userrole_id)))) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + var dbEntities = await Rolemenus.AsNoTracking().Where(t => t.userrole_id == viewModel.userrole_id).ToListAsync(); + + var entities = (from vm in viewModel.detailList + join db in dbEntities on new { id = Math.Abs(vm.id), vm.menu_id } equals new { db.id, db.menu_id } into dbJoin + from db in dbJoin.DefaultIfEmpty() + select new RolemenuEntity + { + id = vm.id, + userrole_id = viewModel.userrole_id, + menu_id = vm.menu_id, + authority = vm.authority, + create_time = db == null ? DateTime.Now : db.create_time, + last_update_time = DateTime.Now, + tenant_id = currentUser.tenant_id + }).ToList(); + + if (entities.Any(t => t.id > 0)) + { + Rolemenus.UpdateRange(entities.Where(t => t.id > 0).ToList()); + } + if (entities.Any(t => t.id == 0)) + { + Rolemenus.AddRange(entities.Where(t => t.id == 0).ToList()); + } + if (entities.Any(t => t.id < 0)) + { + var dels = entities.Where(t => t.id < 0).ToList(); + dels.ForEach(t => t.id *= -1); + Rolemenus.RemoveRange(dels); + } + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// userrole id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int userrole_id) + { + var qty = await _dBContext.GetDbSet().Where(t => t.userrole_id.Equals(userrole_id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/Services/Sku/CategoryService.cs b/backend/ModernWMS.WMS/Services/Sku/CategoryService.cs new file mode 100644 index 0000000..fd415e0 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Sku/CategoryService.cs @@ -0,0 +1,208 @@ +/* + * date:2022-12-20 + * developer:AMo + */ + using Mapster; + using Microsoft.EntityFrameworkCore; + using ModernWMS.Core.DBContext; + using ModernWMS.Core.Services; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; +using ModernWMS.Core.JWT; +using System.Collections.Immutable; +using System.Collections.Generic; + +namespace ModernWMS.WMS.Services + { + /// + /// Category Service + /// + public class CategoryService : BaseService, ICategoryService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Category constructor + /// + /// The DBContext + /// Localizer + public CategoryService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// Get all records + /// + /// currentUser + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking() + .Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + .ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.AsNoTracking().FirstOrDefaultAsync(t => t.id.Equals(id)); + if (entity == null) + { + return new CategoryViewModel(); + } + return entity.Adapt(); + } + /// + /// add a new record + /// + /// viewmodel + /// currentUser + /// + public async Task<(int id, string msg)> AddAsync(CategoryViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AsNoTracking().AnyAsync(t => t.tenant_id.Equals(currentUser.tenant_id) && t.category_name.Equals(viewModel.category_name))) + { + return (0, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["category_name"], viewModel.category_name)); + } + var entity = viewModel.Adapt(); + entity.id = 0; + entity.creator = currentUser.user_name; + entity.create_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + entity.is_valid = viewModel.is_valid; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// + public async Task<(bool flag, string msg)> UpdateAsync(CategoryViewModel viewModel) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + if (await DbSet.AsNoTracking().AnyAsync(t => !t.id.Equals(viewModel.id) && t.tenant_id.Equals(entity.tenant_id) && t.category_name.Equals(viewModel.category_name))) + { + return (false, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["category_name"], viewModel.category_name)); + } + entity.id = viewModel.id; + entity.category_name = viewModel.category_name; + entity.parent_id = viewModel.parent_id; + entity.last_update_time = DateTime.Now; + if (!viewModel.is_valid.Equals(entity.is_valid)) + { + var entities = await DbSet.Where(t => t.parent_id > 0).ToListAsync(); + List children = new List(); + GetChildren(entities, entity.id, ref children); + if (children.Any()) + { + children.ForEach(c => + { + c.is_valid = viewModel.is_valid; + c.last_update_time = DateTime.Now; + }); + } + } + entity.is_valid = viewModel.is_valid; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + private void GetChildren(List entities, int parentId, ref List children) + { + var data = entities.Where(t => t.parent_id== parentId).ToList(); + if (data.Any()) + { + foreach (var item in data) + { + children.Add(item); + if (entities.Any(t => t.parent_id.Equals(item.id))) + { + GetChildren(entities, item.parent_id, ref children); + } + } + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var entities = await DbSet.Where(t => t.parent_id.Equals(id)).ToListAsync(); + List children = new List(); + GetChildren(entities, id, ref children); + List idList = new List { id }; + if (children.Any()) + { + idList.AddRange(children.Select(t => t.id).ToList()); + } + // 判断是否引用 + var Spus = _dBContext.GetDbSet(); + if (await Spus.AsNoTracking().AnyAsync(t => idList.Contains(t.category_id))) + { + return (false, _stringLocalizer["delete_referenced"]); + } + var qty = await _dBContext.GetDbSet().Where(t => idList.Contains(t.id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/Services/Sku/SpuService.cs b/backend/ModernWMS.WMS/Services/Sku/SpuService.cs new file mode 100644 index 0000000..581fe5d --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Sku/SpuService.cs @@ -0,0 +1,452 @@ +/* + * date:2022-12-21 + * developer:AMo + */ + using Mapster; + using Microsoft.EntityFrameworkCore; + using ModernWMS.Core.DBContext; + using ModernWMS.Core.Services; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; +using ModernWMS.Core.DynamicSearch; +using ModernWMS.Core.Models; +using ModernWMS.Core.JWT; + +namespace ModernWMS.WMS.Services +{ + /// + /// Spu Service + /// + public class SpuService : BaseService, ISpuService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Spu constructor + /// + /// The DBContext + /// Localizer + public SpuService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var Categorys = _dBContext.GetDbSet(); + var Spus = _dBContext.GetDbSet(); + var Skus = _dBContext.GetDbSet(); + var query = from m in Spus.AsNoTracking() + join c in Categorys.AsNoTracking() on m.category_id equals c.id + where m.tenant_id == currentUser.tenant_id + select new SpuBothViewModel + { + id = m.id, + spu_code = m.spu_code, + spu_name = m.spu_name, + category_id = m.category_id, + category_name = c.category_name, + spu_description = m.spu_description, + bar_code = m.bar_code, + supplier_id = m.supplier_id, + supplier_name = m.supplier_name, + brand = m.brand, + origin = m.origin, + length_unit = m.length_unit, + volume_unit = m.volume_unit, + weight_unit = m.weight_unit, + creator = m.creator, + create_time = m.create_time, + last_update_time = m.last_update_time, + is_valid = m.is_valid, + detailList = Skus.AsNoTracking().Where(t => t.spu_id.Equals(m.id)) + .Select(t => new SkuViewModel + { + id = t.id, + spu_id = t.spu_id, + sku_code = t.sku_code, + sku_name = t.sku_name, + weight = t.weight, + lenght = t.lenght, + width = t.width, + height = t.height, + volume = t.volume, + unit = t.unit, + cost = t.cost, + price = t.price, + create_time = t.create_time, + last_update_time = t.last_update_time + }).ToList() + + }; + query = query.Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var Categorys = _dBContext.GetDbSet(); + var Spus = _dBContext.GetDbSet(); + var Skus = _dBContext.GetDbSet(); + var query = from m in Spus.AsNoTracking() + join c in Categorys.AsNoTracking() on m.category_id equals c.id + where m.id == id + select new SpuBothViewModel + { + id = m.id, + spu_code = m.spu_code, + spu_name = m.spu_name, + category_id = m.category_id, + category_name = c.category_name, + spu_description = m.spu_description, + bar_code = m.bar_code, + supplier_id = m.supplier_id, + supplier_name = m.supplier_name, + brand = m.brand, + origin = m.origin, + length_unit = m.length_unit, + volume_unit = m.volume_unit, + weight_unit = m.weight_unit, + creator = m.creator, + create_time = m.create_time, + last_update_time = m.last_update_time, + is_valid = m.is_valid, + detailList = Skus.Where(t => t.spu_id.Equals(m.id)) + .Select(t => new SkuViewModel + { + id = t.id, + spu_id = t.spu_id, + sku_code = t.sku_code, + sku_name = t.sku_name, + weight = t.weight, + lenght = t.lenght, + width = t.width, + height = t.height, + volume = t.volume, + unit = t.unit, + cost = t.cost, + price = t.price, + create_time = t.create_time, + last_update_time = t.last_update_time + }).ToList() + + }; + var data = await query.FirstOrDefaultAsync(); + if (data != null) + { + return data; + } + else + { + return new SpuBothViewModel(); + } + } + /// + /// get sku info by sku_id + /// + /// sku_id + /// + public async Task GetSkuAsync(int sku_id) + { + var Categorys = _dBContext.GetDbSet(); + var Spus = _dBContext.GetDbSet(); + var Skus = _dBContext.GetDbSet(); + var query = from m in Spus.AsNoTracking() + join c in Categorys.AsNoTracking() on m.category_id equals c.id + join d in Skus.AsNoTracking() on m.id equals d.spu_id + where d.id == sku_id + select new SkuDetailViewModel + { + spu_id = m.id, + spu_code = m.spu_code, + spu_name = m.spu_name, + category_id = m.category_id, + category_name = c.category_name, + spu_description = m.spu_description, + bar_code = m.bar_code, + supplier_id = m.supplier_id, + supplier_name = m.supplier_name, + brand = m.brand, + origin = m.origin, + length_unit = m.length_unit, + volume_unit = m.volume_unit, + weight_unit = m.weight_unit, + sku_id = d.id, + sku_code = d.sku_code, + sku_name = d.sku_name, + weight = d.weight, + lenght = d.lenght, + width = d.width, + height = d.height, + volume = d.volume, + unit = d.unit, + cost = d.cost, + price = d.price + }; + var data = await query.FirstOrDefaultAsync(); + if (data != null) + { + return data; + } + else + { + return new SkuDetailViewModel(); + } + + } + + /// + /// add a new record + /// + /// viewmodel + /// currentUser + /// + public async Task<(int id, string msg)> AddAsync(SpuBothViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AsNoTracking().AnyAsync(t => t.tenant_id.Equals(currentUser.tenant_id) && t.spu_code.Equals(viewModel.spu_code))) + { + return (0, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["spu_code"], viewModel.spu_code)); + } + var entity = viewModel.Adapt(); + entity.id = 0; + entity.creator = currentUser.user_name; + entity.create_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + if (viewModel.detailList.Any()) + { + decimal dec = ChangeLengthUnit(entity.length_unit, entity.volume_unit); + viewModel.detailList.ForEach(t => + { + t.id = 0; + t.volume = Math.Round(t.lenght * dec * t.width * dec * t.height * dec, 3); + }); + } + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// change to the volume unit + /// + /// length_unit + /// volume_unit + /// + private decimal ChangeLengthUnit(byte length_unit, byte volume_unit) + { + if (volume_unit.Equals(0)) // cm3 + { + if (length_unit.Equals(0)) //mm + { + return 0.1M; + } + else if (length_unit.Equals(2)) // dm + { + return 10M; + } + else if (length_unit.Equals(3)) // m + { + return 100M; + } + else // cm + { + return 1M; + } + } + else if (volume_unit.Equals(1)) // dm3 + { + if (length_unit.Equals(0)) + { + return 0.01M; + } + else if (length_unit.Equals(2)) + { + return 1M; + } + else if (length_unit.Equals(3)) + { + return 10M; + } + else + { + return 0.1M; + } + } + else if (volume_unit.Equals(2)) // m3 + { + if (length_unit.Equals(0)) + { + return 0.001M; + } + else if (length_unit.Equals(2)) + { + return 0.1M; + } + else if (length_unit.Equals(3)) + { + return 1M; + } + else + { + return 0.01M; + } + } + else + { + return 1M; + } + + } + /// + /// update a record + /// + /// args + /// + public async Task<(bool flag, string msg)> UpdateAsync(SpuBothViewModel viewModel) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.Include(d => d.detailList).FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + if (await DbSet.AsNoTracking().AnyAsync(t => !t.id.Equals(viewModel.id) && t.tenant_id.Equals(entity.tenant_id) && t.spu_code.Equals(viewModel.spu_code))) + { + return (false, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["spu_code"], viewModel.spu_code)); + } + entity.spu_code = viewModel.spu_code; + entity.spu_name = viewModel.spu_name; + entity.category_id = viewModel.category_id; + entity.spu_description = viewModel.spu_description; + entity.bar_code = viewModel.bar_code; + entity.supplier_id = viewModel.supplier_id; + entity.supplier_name = viewModel.supplier_name; + entity.brand = viewModel.brand; + entity.origin = viewModel.origin; + entity.length_unit = viewModel.length_unit; + entity.volume_unit = viewModel.volume_unit; + entity.weight_unit = viewModel.weight_unit; + entity.is_valid = viewModel.is_valid; + entity.last_update_time = DateTime.Now; + + + if (viewModel.detailList.Any(t => t.id > 0)) + { + entity.detailList.ForEach(d => + { + var vm = viewModel.detailList.Where(t => t.id > 0).FirstOrDefault(t => t.id == d.id); + if (vm != null) + { + d.sku_code = vm.sku_code; + d.sku_name = vm.sku_name; + d.weight = vm.weight; + d.lenght = vm.lenght; + d.width = vm.width; + d.height = vm.height; + d.volume = vm.volume; + d.unit = vm.unit; + d.cost = vm.cost; + d.price = vm.price; + d.last_update_time = DateTime.Now; + } + }); + } + if (viewModel.detailList.Any(t => t.id == 0)) + { + entity.detailList.AddRange(viewModel.detailList.Where(t => t.id == 0).ToList().Adapt>()); + } + if (viewModel.detailList.Any(t => t.id < 0)) + { + var delIds = viewModel.detailList.Where(t => t.id < 0).Select(t => t.id * -1).ToList(); + entity.detailList.RemoveAll(entity => delIds.Contains(entity.id)); + } + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + decimal dec = ChangeLengthUnit(entity.length_unit, entity.volume_unit); + await _dBContext.GetDbSet().Where(t => t.spu_id.Equals(entity.id)) + .ExecuteUpdateAsync(p => p.SetProperty(x => x.volume, x => Math.Round(x.lenght * dec * x.width * dec * x.height * dec, 3))); + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var Asns = _dBContext.GetDbSet(); + if(await Asns.AsNoTracking().AnyAsync(t => t.spu_id.Equals(id))) + { + return (false, _stringLocalizer["delete_referenced"]); + } + var qty = await _dBContext.GetDbSet().Where(t => t.spu_id.Equals(id)).ExecuteDeleteAsync(); + qty += await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/Services/Stock/StockService.cs b/backend/ModernWMS.WMS/Services/Stock/StockService.cs new file mode 100644 index 0000000..d47d3d5 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Stock/StockService.cs @@ -0,0 +1,427 @@ +/* + * date:2022-12-22 + * developer:NoNo + */ +using Mapster; +using Microsoft.EntityFrameworkCore; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using ModernWMS.Core.Models; +using ModernWMS.Core.JWT; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DynamicSearch; +using System.Runtime.Intrinsics.Arm; +using System.Net.WebSockets; +using System.Linq; + +namespace ModernWMS.WMS.Services +{ + /// + /// Stock Service + /// + public class StockService : BaseService, IStockService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Stock constructor + /// + /// The DBContext + /// Localizer + public StockService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + + + /// + /// stock page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> StockPageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + + var DbSet = _dBContext.GetDbSet().Where(t => t.tenant_id.Equals(currentUser.tenant_id)); + var asn_DBSet = _dBContext.GetDbSet().Where(t => t.tenant_id.Equals(currentUser.tenant_id)); + var dispatch_DBSet = _dBContext.GetDbSet().Where(t => t.tenant_id.Equals(currentUser.tenant_id)); + var sku_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var spu_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var processdetail_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var move_DBSet = _dBContext.GetDbSet(); + var stock_group_datas = from stock in DbSet.AsNoTracking() + join gl in _dBContext.GetDbSet().AsNoTracking() on stock.goods_location_id equals gl.id + group new { stock ,gl} by stock.sku_id into sg + select new + { + sku_id = sg.Key, + qty_frozen = sg.Where(t => t.stock.is_freeze == true).Sum(e => e.stock.qty), + qty = sg.Sum(t => t.stock.qty), + qty_normal = sg.Where(t=>t.gl.warehouse_area_property != 5).Sum(t=>t.stock.qty), + qty_normal_frozen = sg.Where(t=>t.gl.warehouse_area_property != 5 && t.stock.is_freeze == true).Sum(t=>t.stock.qty), + }; + var asn_group_datas = from asn in asn_DBSet.AsNoTracking() + group asn by asn.sku_id into ag + select new + { + sku_id = ag.Key, + qty_asn = ag.Where(t => t.asn_status == 0).Sum(t => t.asn_qty), + qty_to_unload = ag.Where(t => t.asn_status == 1).Sum(t => t.asn_qty), + qty_to_sort = ag.Where(t => t.asn_status == 2).Sum(t => t.asn_qty), + qty_sorted = ag.Where(t => t.asn_status == 3).Sum(t => t.sorted_qty), + shortage_qty = ag.Where(t => t.asn_status == 4).Sum(t => t.shortage_qty) + }; + var dispatch_group_datas = from dp in dispatch_DBSet.AsNoTracking() + group dp by dp.sku_id into dg + select new + { + sku_id = dg.Key, + qty_locked = dg.Sum(t => t.lock_qty) + }; + var process_locked_group_datas = from pd in processdetail_DBSet + join gl in _dBContext.GetDbSet().AsNoTracking() on pd.goods_location_id equals gl.id + where pd.is_update_stock == false && pd.is_source == true + group new { pd , gl } by pd.sku_id into pdg + select new + { + sku_id = pdg.Key, + qty_locked = pdg.Sum(t => t.pd.qty), + qty_normal_locked = pdg.Where(t => t.gl.warehouse_area_property != 5).Sum(t => t.pd.qty), + }; + var move_locked_group_datas = from m in move_DBSet.AsNoTracking() + join gl in _dBContext.GetDbSet().AsNoTracking() on m.orig_goods_location_id equals gl.id + where m.move_status == 0 + group new { m , gl } by m.sku_id into mg + select new + { + sku_id = mg.Key, + qty_locked = mg.Sum(t => t.m.qty), + qty_normal_locked = mg.Where(t=>t.gl.warehouse_area_property !=5).Sum(t => t.m.qty), + }; + + var query = from sku in sku_DBSet + join ag in asn_group_datas on sku.id equals ag.sku_id into ag_left + from ag in ag_left.DefaultIfEmpty() + join sg in stock_group_datas on sku.id equals sg.sku_id into sg_left + from sg in sg_left.DefaultIfEmpty() + join dp in dispatch_group_datas on sg.sku_id equals dp.sku_id into dp_left + from dp in dp_left.DefaultIfEmpty() + join pl in process_locked_group_datas on sku.id equals pl.sku_id into pl_left + from pl in pl_left.DefaultIfEmpty() + join m in move_locked_group_datas on sku.id equals m.sku_id into m_left + from m in m_left.DefaultIfEmpty() + join spu in spu_DBSet on sku.spu_id equals spu.id + where spu.tenant_id == currentUser.tenant_id + select new StockManagementViewModel + { + sku_id = sku.id, + spu_name = spu.spu_name, + spu_code = spu.spu_code, + sku_code = sku.sku_code, + qty_asn = ag.qty_asn == null ? 0: ag.qty_asn, + qty_available = (sg.qty_normal == null ? 0 : sg.qty_normal) - (sg.qty_normal_frozen == null ? 0 : sg.qty_normal_frozen) - (dp.qty_locked == null ? 0 : dp.qty_locked) - (pl.qty_normal_locked == null ? 0 : pl.qty_normal_locked) - (m.qty_normal_locked == null ? 0 : m.qty_normal_locked) , + qty_frozen = sg.qty_frozen == null ? 0 : sg.qty_frozen, + qty_locked = (dp.qty_locked == null ? 0 : dp.qty_locked) + (pl.qty_locked == null ? 0 : pl.qty_locked) + (m.qty_locked == null ? 0:m.qty_locked), + qty_sorted = ag.qty_sorted==null?0:ag.qty_sorted, + qty_to_sort = ag.qty_to_sort == null ? 0 : ag.qty_to_sort, + shortage_qty = ag.shortage_qty == null ? 0 : ag.shortage_qty, + qty_to_unload = ag.qty_to_unload == null ? 0 : ag.qty_to_unload, + qty = sg.qty == null ? 0 : sg.qty, + }; + query = query.Where(t=>t.qty_asn>0 || t.qty > 0).Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderBy(t => t.sku_code) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + + /// + /// location stock page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> LocationStockPageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + + var DbSet = _dBContext.GetDbSet().Where(t => t.tenant_id.Equals(currentUser.tenant_id)); + var dispatchpick_DBSet = _dBContext.GetDbSet(); + var dispatch_DBSet = _dBContext.GetDbSet().Where(t => t.tenant_id.Equals(currentUser.tenant_id)); + var sku_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var spu_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var location_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var processdetail_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var move_DBSet = _dBContext.GetDbSet(); + + var stock_group_datas = from stock in DbSet.AsNoTracking() + where stock.tenant_id == currentUser.tenant_id + group stock by new { stock.sku_id, stock.goods_location_id } into sg + select new + { + sku_id = sg.Key.sku_id, + goods_location_id = sg.Key.goods_location_id, + qty_frozen = sg.Where(t => t.is_freeze == true).Sum(e => e.qty), + qty = sg.Sum(t => t.qty) + }; + + var dispatch_group_datas = from dp in dispatch_DBSet.AsNoTracking() + join dpp in dispatchpick_DBSet.AsNoTracking() on dp.id equals dpp.dispatchlist_id + where dp.dispatch_status > 1 && dp.dispatch_status < 6 + group dpp by new { dpp.sku_id, dpp.goods_location_id } into dg + select new + { + sku_id = dg.Key.sku_id, + goods_location_id = dg.Key.goods_location_id, + qty_locked = dg.Sum(t => t.pick_qty) + }; + var process_locked_group_datas = from pd in processdetail_DBSet + where pd.is_update_stock == false && pd.is_source == true + group pd by new { pd.sku_id, pd.goods_location_id } into pdg + select new + { + sku_id = pdg.Key.sku_id, + goods_location_id = pdg.Key.goods_location_id, + qty_locked = pdg.Sum(t => t.qty) + }; + + var move_locked_group_datas = from m in move_DBSet.AsNoTracking() + where m.move_status == 0 + group m by new { m.sku_id, m.orig_goods_location_id } into mg + select new + { + sku_id = mg.Key.sku_id, + goods_location_id = mg.Key.orig_goods_location_id, + qty_locked = mg.Sum(t => t.qty) + }; + var query = from sg in stock_group_datas + join dp in dispatch_group_datas on new { sg.sku_id, sg.goods_location_id } equals new { dp.sku_id, dp.goods_location_id } into dp_left + from dp in dp_left.DefaultIfEmpty() + join pl in process_locked_group_datas on new { sg.sku_id, sg.goods_location_id } equals new { pl.sku_id, pl.goods_location_id } into pl_left + from pl in pl_left.DefaultIfEmpty() + join m in move_locked_group_datas on new { sg.sku_id, sg.goods_location_id } equals new { m.sku_id, m.goods_location_id } into m_left + from m in m_left.DefaultIfEmpty() + join sku in sku_DBSet on sg.sku_id equals sku.id + join spu in spu_DBSet on sku.spu_id equals spu.id + join gl in location_DBSet on sg.goods_location_id equals gl.id + select new LocationStockManagementViewModel + { + sku_id = sg.sku_id, + spu_name = spu.spu_name, + spu_code = spu.spu_code, + sku_code = sku.sku_code, + sku_name = sku.sku_name, + qty_available =gl.warehouse_area_property == 5?0:( sg.qty - sg.qty_frozen - (dp.qty_locked == null ? 0 : dp.qty_locked) - (pl.qty_locked == null ? 0 : pl.qty_locked) - (m.qty_locked == null ? 0 : m.qty_locked)), + qty_frozen = sg.qty_frozen, + qty_locked = (dp.qty_locked == null ? 0 : dp.qty_locked) + (pl.qty_locked == null ? 0 : pl.qty_locked)+ (m.qty_locked == null ? 0 : m.qty_locked), + qty = sg.qty, + location_name = gl.location_name, + warehouse_name = gl.warehouse_name, + }; + query = query.Where(t => t.qty > 0).Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderBy(t => t.sku_code) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + + /// + /// page search select + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> SelectPageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + + var DbSet = _dBContext.GetDbSet().Where(t => t.tenant_id.Equals(currentUser.tenant_id)); + var dispatchpick_DBSet = _dBContext.GetDbSet(); + var dispatch_DBSet = _dBContext.GetDbSet().Where(t => t.tenant_id.Equals(currentUser.tenant_id)); + var sku_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var spu_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var location_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var processdetail_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var move_DBSet = _dBContext.GetDbSet(); + + var dispatch_group_datas = from dp in dispatch_DBSet.AsNoTracking() + join dpp in dispatchpick_DBSet.AsNoTracking() on dp.id equals dpp.dispatchlist_id + where dp.dispatch_status > 1 && dp.dispatch_status < 6 + group dpp by new { dpp.sku_id, dpp.goods_location_id, dpp.goods_owner_id } into dg + select new + { + goods_owner_id = dg.Key.goods_owner_id, + sku_id = dg.Key.sku_id, + goods_location_id = dg.Key.goods_location_id, + qty_locked = dg.Sum(t => t.pick_qty) + }; + var process_locked_group_datas = from pd in processdetail_DBSet + where pd.is_update_stock == false && pd.is_source == true + group pd by new { pd.sku_id, pd.goods_location_id, pd.goods_owner_id } into pdg + select new + { + goods_owner_id = pdg.Key.goods_owner_id, + sku_id = pdg.Key.sku_id, + goods_location_id = pdg.Key.goods_location_id, + qty_locked = pdg.Sum(t => t.qty) + }; + var move_locked_group_datas = from m in move_DBSet.AsNoTracking() + where m.move_status == 0 + group m by new { m.sku_id, m.orig_goods_location_id, m.goods_owner_id } into mg + select new + { + goods_owner_id = mg.Key.goods_owner_id, + sku_id = mg.Key.sku_id, + goods_location_id = mg.Key.orig_goods_location_id, + qty_locked = mg.Sum(t => t.qty) + }; + var query = from sg in DbSet.AsNoTracking() + join dp in dispatch_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { dp.sku_id, dp.goods_location_id, dp.goods_owner_id } into dp_left + from dp in dp_left.DefaultIfEmpty() + join pl in process_locked_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { pl.sku_id, pl.goods_location_id, pl.goods_owner_id } into pl_left + from pl in pl_left.DefaultIfEmpty() + join m in move_locked_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { m.sku_id, m.goods_location_id, m.goods_owner_id } into m_left + from m in m_left.DefaultIfEmpty() + join sku in sku_DBSet on sg.sku_id equals sku.id + join spu in spu_DBSet on sku.spu_id equals spu.id + join gl in location_DBSet on sg.goods_location_id equals gl.id + join owner in _dBContext.GetDbSet().AsNoTracking() on sg.goods_owner_id equals owner.id into o_left + from owner in o_left.DefaultIfEmpty() + where sg.tenant_id == currentUser.tenant_id + group new {sg,dp,pl,m,sku,spu,gl} by new { sg.sku_id ,spu.spu_name , spu.spu_code, sku.sku_code,sku.sku_name,sg.goods_location_id,sg.goods_owner_id,owner.goods_owner_name + , sg.qty , gl.location_name, sg.is_freeze, gl.warehouse_name ,sg.id,sku.unit,sg.tenant_id} into g + select new StockViewModel + { + sku_id = g.Key.sku_id, + spu_name = g.Key.spu_name, + spu_code = g.Key.spu_code, + sku_code = g.Key.sku_code, + sku_name = g.Key.sku_name, + qty_available = g.Key.is_freeze ? 0 : (g.Key.qty - g.Sum(t=>t.dp.qty_locked == null ? 0 : t.dp.qty_locked) - g.Sum(t => t.pl.qty_locked == null ? 0 : t.pl.qty_locked) - g.Sum(t=>(t.m.qty_locked == null ? 0 : t.m.qty_locked))), + qty = g.Key.qty, + goods_location_id= g.Key.goods_location_id, + goods_owner_id = g.Key.goods_owner_id, + location_name = g.Key.location_name, + warehouse_name = g.Key.warehouse_name, + is_freeze = g.Key.is_freeze, + id = g.Key.id, + tenant_id = g.Key.tenant_id, + unit = g.Key.unit, + goods_owner_name = g.Key.goods_owner_name == null? "":g.Key.goods_owner_name, + }; + if(pageSearch.sqlTitle == "") + { + query = query.Where(t => t.qty_available > 0); + } + else if(pageSearch.sqlTitle == "all") + { + + } + else if(pageSearch.sqlTitle == "frozen") + { + query = query.Where(t => t.is_freeze == true); + } + query = query.Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderBy(t => t.sku_code) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + + /// + /// sku page search select + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> SkuSelectPageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var sku_DBSet = _dBContext.GetDbSet(); + var spu_DBSet = _dBContext.GetDbSet(); + var query = from sku in sku_DBSet.AsNoTracking() + join spu in spu_DBSet.AsNoTracking() on sku.spu_id equals spu.id + where spu.tenant_id == currentUser.tenant_id + select new SkuSelectViewModel + { + spu_id = sku.spu_id, + sku_code = sku.sku_code, + sku_name = sku.sku_name, + unit = sku.unit, + spu_code = spu.spu_code, + spu_name = spu.spu_name, + supplier_id = spu.supplier_id, + supplier_name = spu.supplier_name, + brand = spu.brand, + origin = spu.origin, + sku_id = sku.id + }; + query = query.Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderBy(t => t.sku_code) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/Services/Stockadjust/StockadjustService.cs b/backend/ModernWMS.WMS/Services/Stockadjust/StockadjustService.cs new file mode 100644 index 0000000..9f231f4 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Stockadjust/StockadjustService.cs @@ -0,0 +1,280 @@ +/* + * date:2022-12-26 + * developer:NoNo + */ + using Mapster; + using Microsoft.EntityFrameworkCore; + using ModernWMS.Core.DBContext; + using ModernWMS.Core.Services; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using ModernWMS.Core.Models; + using ModernWMS.Core.JWT; + using Microsoft.Extensions.Localization; + using ModernWMS.Core.DynamicSearch; +using System.Net.Quic; + +namespace ModernWMS.WMS.Services + { + /// + /// Stockadjust Service + /// + public class StockadjustService : BaseService, IStockadjustService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Stockadjust constructor + /// + /// The DBContext + /// Localizer + public StockadjustService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var Stockadjusts = _dBContext.GetDbSet(); + var Spus = _dBContext.GetDbSet(); + var Skus = _dBContext.GetDbSet(); + var Goodsowners = _dBContext.GetDbSet(); + var Goodslocations = _dBContext.GetDbSet(); + var query = from sj in Stockadjusts.AsNoTracking() + join sku in Skus.AsNoTracking() on sj.sku_id equals sku.id + join spu in Spus.AsNoTracking() on sku.spu_id equals spu.id + join gsl in Goodslocations.AsNoTracking() on sj.goods_location_id equals gsl.id + join gso in Goodsowners.AsNoTracking() on sj.goods_owner_id equals gso.id into gsoJoin + from gso in gsoJoin.DefaultIfEmpty() + where sj.tenant_id == currentUser.tenant_id + select new StockadjustViewModel + { + id = sj.id, + job_code = sj.job_code, + is_update_stock = sj.is_update_stock, + job_type = sj.job_type, + qty = sj.qty, + source_table_id = sj.source_table_id, + tenant_id = sj.tenant_id, + sku_id = sku.id, + sku_code = sku.sku_code, + sku_name = sku.sku_name, + spu_code = spu.spu_code, + spu_name = spu.spu_name, + goods_location_id = sj.goods_location_id, + warehouse_name = gsl.warehouse_name, + location_name = gsl.location_name, + goods_owner_id = sj.goods_owner_id, + goods_owner_name = gso.goods_owner_name == null ? string.Empty : gso.goods_owner_name, + creator = sj.creator, + create_time = sj.create_time, + last_update_time = sj.last_update_time + }; + query = query.Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking().Where(t=>t.tenant_id.Equals(currentUser.tenant_id)).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.AsNoTracking().FirstOrDefaultAsync(t=>t.id.Equals(id)); + if (entity == null) + { + return null; + } + return entity.Adapt(); + } + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + public async Task<(int id, string msg)> AddAsync(StockadjustViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var entity = viewModel.Adapt(); + entity.id = 0; + entity.create_time = DateTime.Now; + entity.creator = currentUser.user_name; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// + public async Task<(bool flag, string msg)> UpdateAsync(StockadjustViewModel viewModel) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false,_stringLocalizer[ "not_exists_entity"]); + } + entity.id = viewModel.id; + entity.job_code = viewModel.job_code; + entity.sku_id = viewModel.sku_id; + entity.goods_owner_id = viewModel.goods_owner_id; + entity.goods_location_id = viewModel.goods_location_id; + entity.qty = viewModel.qty; + entity.is_update_stock = viewModel.is_update_stock; + entity.job_type = viewModel.job_type; + entity.source_table_id = viewModel.source_table_id; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var DBSet = _dBContext.GetDbSet(); + var entity = await DBSet.Where(t=>t.id == id).FirstOrDefaultAsync(); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + DBSet.Remove(entity); + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + + /// + /// confirm adjustment + /// + /// id + /// + public async Task<(bool flag, string msg)> ConfirmAdjustment(int id) + { + var adjust_DBset = _dBContext.GetDbSet(); + var entity = await adjust_DBset.FirstOrDefaultAsync(t => t.id == id); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + if(entity.job_type == 2) + { + var processdetail_DBSet = _dBContext.GetDbSet(); + var processdetail = await processdetail_DBSet.Where(t => t.id == entity.source_table_id).FirstOrDefaultAsync(); + if (processdetail != null) + { + processdetail.last_update_time = DateTime.Now; + processdetail.is_update_stock = true; + } + } + var stock_DBSet = _dBContext.GetDbSet(); + var stock = await stock_DBSet.Where(t=>t.goods_location_id == entity.goods_location_id&&t.sku_id== entity.sku_id).FirstOrDefaultAsync(); + if(stock == null) + { + stock = new StockEntity + { + id = entity.id, + sku_id = entity.sku_id, + goods_location_id = entity.goods_location_id, + qty = entity.qty, + goods_owner_id = entity.goods_owner_id, + is_freeze = false, + last_update_time = DateTime.Now, + tenant_id = entity.tenant_id, + }; + } + else + { + stock.qty += entity.qty; + stock.goods_owner_id= entity.goods_owner_id; + stock.last_update_time= DateTime.Now; + } + entity.is_update_stock = true; + entity.last_update_time = DateTime.Now; + var res = await _dBContext.SaveChangesAsync(); + if (res > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + return (false, _stringLocalizer["operation_failed"]); + } + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/Services/Stockfreeze/StockfreezeService.cs b/backend/ModernWMS.WMS/Services/Stockfreeze/StockfreezeService.cs new file mode 100644 index 0000000..9f4a2aa --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Stockfreeze/StockfreezeService.cs @@ -0,0 +1,288 @@ +/* + * date:2022-12-26 + * developer:NoNo + */ +using Mapster; +using Microsoft.EntityFrameworkCore; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using ModernWMS.Core.Models; +using ModernWMS.Core.JWT; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DynamicSearch; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using Microsoft.CodeAnalysis; + +namespace ModernWMS.WMS.Services +{ + /// + /// Stockfreeze Service + /// + public class StockfreezeService : BaseService, IStockfreezeService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Stockfreeze constructor + /// + /// The DBContext + /// Localizer + public StockfreezeService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet(); + + var query = from m in DbSet.AsNoTracking() + join sku in _dBContext.GetDbSet().AsNoTracking() on m.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + join location in _dBContext.GetDbSet().AsNoTracking() on m.goods_location_id equals location.id + select new StockfreezeViewModel + { + id = m.id, + job_code = m.job_code, + job_type = m.job_type, + sku_id = m.sku_id, + goods_owner_id = m.goods_owner_id, + goods_location_id = m.goods_location_id, + handler = m.handler, + handle_time = m.handle_time, + last_update_time = m.last_update_time, + tenant_id = m.tenant_id, + sku_code = sku.sku_code, + spu_code = spu.spu_code, + spu_name = spu.spu_name, + location_name = location.location_name, + warehouse_name = location.warehouse_name + }; + query = query + .Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + .Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.handle_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking().Where(t => t.tenant_id.Equals(currentUser.tenant_id)).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var data = await (from m in DbSet.AsNoTracking() + join sku in _dBContext.GetDbSet().AsNoTracking() on m.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + join location in _dBContext.GetDbSet().AsNoTracking() on m.goods_location_id equals location.id + where m.id == id + select new StockfreezeViewModel + { + id = m.id, + job_code = m.job_code, + job_type = m.job_type, + sku_id = m.sku_id, + goods_owner_id = m.goods_owner_id, + goods_location_id = m.goods_location_id, + handler = m.handler, + handle_time = m.handle_time, + last_update_time = m.last_update_time, + tenant_id = m.tenant_id, + sku_code = sku.sku_code, + spu_code = spu.spu_code, + spu_name = spu.spu_name, + location_name = location.location_name, + warehouse_name = location.warehouse_name + }).FirstOrDefaultAsync(); + if (data == null) + { + return null; + } + return data; + } + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + public async Task<(int id, string msg)> AddAsync(StockfreezeViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var entity = viewModel.Adapt(); + entity.id = 0; + entity.handle_time = DateTime.Now; + entity.handler = currentUser.user_name; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + entity.job_code = await GetOrderCode(currentUser); + var stock_DBSet = _dBContext.GetDbSet(); + var stocks = await stock_DBSet.Where(t => t.goods_location_id == entity.goods_location_id&& t.goods_owner_id == entity.goods_owner_id && t.sku_id == entity.sku_id).ToListAsync(); + foreach (var stock in stocks) + { + if (entity.job_type == true) + stock.is_freeze = true; + else + stock.is_freeze = false; + } + await DbSet.AddAsync(entity); + if( await (_dBContext.GetDbSet().AnyAsync(t => t.goods_location_id == entity.goods_location_id && t.goods_owner_id == entity.goods_owner_id && t.sku_id == entity.sku_id && t.is_update_stock == false))) + { + return (0, _stringLocalizer["process_not_comfirm"]); + } + else if (await (_dBContext.GetDbSet().AnyAsync(t => t.goods_location_id == entity.goods_location_id && t.sku_id == entity.sku_id && t.is_update_stock == false))) + { + return (0, _stringLocalizer["dispatch_not_comfirm"]); + } + else if (await (_dBContext.GetDbSet().AnyAsync(t =>( t.orig_goods_location_id == entity.goods_location_id || t.dest_googs_location_id == entity.goods_location_id)&& t.sku_id == entity.sku_id && t.move_status == 0))) + { + return (0, _stringLocalizer["move_not_comfirm"]); + } + else + { + await _dBContext.SaveChangesAsync(); + } + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// + public async Task<(bool flag, string msg)> UpdateAsync(StockfreezeViewModel viewModel) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + entity.id = viewModel.id; + entity.job_code = viewModel.job_code; + entity.job_type = viewModel.job_type; + entity.sku_id = viewModel.sku_id; + entity.goods_owner_id = viewModel.goods_owner_id; + entity.goods_location_id = viewModel.goods_location_id; + entity.handler = viewModel.handler; + entity.handle_time = viewModel.handle_time; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + + /// + /// get next order code number + /// + /// + public async Task GetOrderCode(CurrentUser currentUser) + { + string code; + string date = DateTime.Now.ToString("yyyy" + "MM" + "dd"); + string maxNo = await _dBContext.GetDbSet().AsNoTracking().Where(t=> t.tenant_id == currentUser.tenant_id).MaxAsync(t => t.job_code); + if (maxNo == null) + { + code = date + "-0001"; + } + else + { + string maxDate = maxNo.Substring(0, 8); + string maxDateNo = maxNo.Substring(9, 4); + if (date == maxDate) + { + int.TryParse(maxDateNo, out int dd); + int newDateNo = dd + 1; + code = date + "-" + newDateNo.ToString("0000"); + } + else + { + code = date + "-0001"; + } + } + return code; + } + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/Services/Stockmove/StockmoveService.cs b/backend/ModernWMS.WMS/Services/Stockmove/StockmoveService.cs new file mode 100644 index 0000000..8e5c100 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Stockmove/StockmoveService.cs @@ -0,0 +1,449 @@ +/* + * date:2022-12-27 + * developer:NoNo + */ +using Mapster; +using Microsoft.EntityFrameworkCore; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using ModernWMS.Core.Models; +using ModernWMS.Core.JWT; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DynamicSearch; +using Microsoft.AspNetCore.Mvc; +using static System.Runtime.InteropServices.JavaScript.JSType; +using System; +using ModernWMS.Core.Utility; + +namespace ModernWMS.WMS.Services +{ + /// + /// Stockmove Service + /// + public class StockmoveService : BaseService, IStockmoveService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Stockmove constructor + /// + /// The DBContext + /// Localizer + public StockmoveService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet(); + var location_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var query = from m in DbSet.AsNoTracking() + join sku in _dBContext.GetDbSet().AsNoTracking() on m.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + join orig_location in location_DBSet on m.orig_goods_location_id equals orig_location.id + join dest_location in location_DBSet on m.dest_googs_location_id equals dest_location.id + select new StockmoveViewModel + { + id = m.id, + job_code = m.job_code, + move_status = m.move_status, + sku_id = m.sku_id, + orig_goods_location_id = m.orig_goods_location_id, + dest_googs_location_id = m.dest_googs_location_id, + qty = m.qty, + goods_owner_id = m.goods_owner_id, + handler = m.handler, + handle_time = m.handle_time, + creator = m.creator, + create_time = m.create_time, + last_update_time = m.last_update_time, + tenant_id = m.tenant_id, + sku_code = sku.sku_code, + sku_name = sku.sku_name, + spu_code = spu.spu_code, + spu_name = spu.spu_name, + dest_googs_location_name = dest_location.location_name, + dest_googs_warehouse = dest_location.warehouse_name, + orig_goods_location_name = orig_location.location_name, + orig_goods_warehouse = orig_location.warehouse_name, + }; + query = query.Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + .Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var location_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var data = await(from m in DbSet.AsNoTracking().Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + join sku in _dBContext.GetDbSet().AsNoTracking() on m.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + join orig_location in location_DBSet on m.orig_goods_location_id equals orig_location.id + join dest_location in location_DBSet on m.dest_googs_location_id equals dest_location.id + select new StockmoveViewModel + { + id = m.id, + job_code = m.job_code, + move_status = m.move_status, + sku_id = m.sku_id, + orig_goods_location_id = m.orig_goods_location_id, + dest_googs_location_id = m.dest_googs_location_id, + qty = m.qty, + goods_owner_id = m.goods_owner_id, + handler = m.handler, + handle_time = m.handle_time, + creator = m.creator, + create_time = m.create_time, + last_update_time = m.last_update_time, + tenant_id = m.tenant_id, + sku_code = sku.sku_code, + sku_name = sku.sku_name, + spu_code = spu.spu_code, + spu_name = spu.spu_name, + dest_googs_location_name = dest_location.location_name, + dest_googs_warehouse = dest_location.warehouse_name, + orig_goods_location_name = orig_location.location_name, + orig_goods_warehouse = orig_location.warehouse_name, + } + ).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var location_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var data = await (from m in DbSet.AsNoTracking() + join sku in _dBContext.GetDbSet().AsNoTracking() on m.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + join orig_location in location_DBSet on m.orig_goods_location_id equals orig_location.id + join dest_location in location_DBSet on m.dest_googs_location_id equals dest_location.id + where m.id == id + select new StockmoveViewModel + { + id = m.id, + job_code = m.job_code, + move_status = m.move_status, + sku_id = m.sku_id, + orig_goods_location_id = m.orig_goods_location_id, + dest_googs_location_id = m.dest_googs_location_id, + qty = m.qty, + goods_owner_id = m.goods_owner_id, + handler = m.handler, + handle_time = m.handle_time, + creator = m.creator, + create_time = m.create_time, + last_update_time = m.last_update_time, + tenant_id = m.tenant_id, + sku_code = sku.sku_code, + sku_name = sku.sku_name, + spu_code = spu.spu_code, + spu_name = spu.spu_name, + dest_googs_location_name = dest_location.location_name, + dest_googs_warehouse = dest_location.warehouse_name, + orig_goods_location_name = orig_location.location_name, + orig_goods_warehouse = orig_location.warehouse_name, + }).FirstOrDefaultAsync(); + if (data == null) + { + return null; + } + return data; + } + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + public async Task<(int id, string msg)> AddAsync(StockmoveViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var stock_DBSet = _dBContext.GetDbSet(); + var entity = viewModel.Adapt(); + var processdetail_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var dispatchpick_DBSet = _dBContext.GetDbSet(); + var dispatch_DBSet = _dBContext.GetDbSet().Where(t => t.tenant_id.Equals(currentUser.tenant_id)); + var dispatch_group_datas = from dp in dispatch_DBSet.AsNoTracking() + join dpp in dispatchpick_DBSet.AsNoTracking() on dp.id equals dpp.dispatchlist_id + where dp.dispatch_status > 1 && dp.dispatch_status < 6 + && dpp.goods_location_id == entity.orig_goods_location_id && dpp.sku_id == entity.sku_id + group dpp by new { dpp.sku_id, dpp.goods_location_id } into dg + select new + { + sku_id = dg.Key.sku_id, + goods_location_id = dg.Key.goods_location_id, + qty_locked = dg.Sum(t => t.pick_qty) + }; + var process_locked_group_datas = from pd in processdetail_DBSet + where pd.is_update_stock == false + && pd.sku_id == entity.sku_id && pd.goods_location_id == entity.orig_goods_location_id + group pd by new { pd.sku_id, pd.goods_location_id } into pdg + select new + { + sku_id = pdg.Key.sku_id, + goods_location_id = pdg.Key.goods_location_id, + qty_locked = pdg.Sum(t => t.qty) + }; + var move_locked_group_datas = from sm in DbSet.AsNoTracking() + where sm.move_status == 0 && sm.sku_id == entity.sku_id && sm.orig_goods_location_id == entity.orig_goods_location_id + group sm by new { sm.sku_id, goods_location_id = sm.orig_goods_location_id } into smg + select new { + smg.Key.sku_id, + smg.Key.goods_location_id, + qty_locked = smg.Sum(t => t.qty) + }; + + var orig_stock =await + (from sg in stock_DBSet.AsNoTracking() + join dp in dispatch_group_datas on new { sg.sku_id, sg.goods_location_id } equals new { dp.sku_id, dp.goods_location_id } into dp_left + from dp in dp_left.DefaultIfEmpty() + join pl in process_locked_group_datas on new { sg.sku_id, sg.goods_location_id } equals new { pl.sku_id, pl.goods_location_id } into pl_left + from pl in pl_left.DefaultIfEmpty() + join sm in move_locked_group_datas on new {sg.sku_id,sg.goods_location_id} equals new {sm.sku_id, goods_location_id = sm.goods_location_id} into sm_left + from sm in sm_left.DefaultIfEmpty() + where sg.sku_id == entity.sku_id && sg.goods_location_id == entity.orig_goods_location_id + select new + { + id = sg.id, + qty_available = sg.is_freeze ? 0 : (sg.qty - (dp.qty_locked == null ? 0 : dp.qty_locked) - (pl.qty_locked == null ? 0 : pl.qty_locked) - (sm.qty_locked == null ? 0 : sm.qty_locked)) , + } + ).FirstOrDefaultAsync(); + var dest_stock = await stock_DBSet.FirstOrDefaultAsync(t => t.goods_location_id == entity.dest_googs_location_id && t.sku_id == entity.sku_id); + if(orig_stock == null || orig_stock.qty_available 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// confirm move + /// + /// id + /// current user + /// + public async Task<(bool flag, string msg)> Confirm(int id,CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var stock_DBSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + entity.handler = currentUser.user_name; + entity.handle_time = DateTime.Now; + entity.move_status = 1; + entity.last_update_time = DateTime.Now; + var orig_stock = await stock_DBSet.FirstOrDefaultAsync(t => t.goods_location_id == entity.orig_goods_location_id && t.sku_id == entity.sku_id) ; + var dest_stock = await stock_DBSet.FirstOrDefaultAsync(t=>t.goods_location_id == entity.dest_googs_location_id && t.sku_id!= entity.sku_id); + if (orig_stock != null) + { + if(orig_stock.qty == entity.qty) + { + stock_DBSet.Remove(orig_stock); + } + else + { + orig_stock.qty -= entity.qty; + orig_stock.last_update_time=DateTime.Now; + } + } + if(dest_stock == null) + { + dest_stock = new StockEntity + { + goods_location_id = entity.dest_googs_location_id, + sku_id = entity.sku_id, + goods_owner_id = entity.goods_owner_id, + is_freeze = false, + last_update_time = DateTime.Now, + qty = entity.qty, + tenant_id = entity.tenant_id, + }; + await stock_DBSet.AddAsync(dest_stock); + } + else + { + dest_stock.qty += entity.qty; + dest_stock.last_update_time = DateTime.Now; + } + var saved = false; + int res = 0; + while (!saved) + { + try + { + // Attempt to save changes to the database + res = await _dBContext.SaveChangesAsync(); + saved = true; + } + catch (DbUpdateConcurrencyException ex) + { + foreach (var entry in ex.Entries) + { + if (entry.Entity is StockEntity) + { + var proposedValues = entry.CurrentValues; + var databaseValues = entry.GetDatabaseValues(); + if (UtilConvert.ObjToInt(proposedValues["id"]) == orig_stock.id) + { + if (UtilConvert.ObjToInt(databaseValues["qty"]) - entity.qty < 0) + { + throw new NotSupportedException(_stringLocalizer["try_agin"]); + } + else if(UtilConvert.ObjToInt(databaseValues["qty"]) - entity.qty==0) + { + entry.State = EntityState.Deleted; + } + else + { + entry.State = EntityState.Modified; + proposedValues["qty"] = UtilConvert.ObjToInt(databaseValues["qty"]) - entity.qty; + } + } + else if(UtilConvert.ObjToInt(proposedValues["id"]) == dest_stock.id) + { + proposedValues["qty"] = UtilConvert.ObjToInt(databaseValues["qty"]) + entity.qty; + } + // Refresh original values to bypass next concurrency check + entry.OriginalValues.SetValues(databaseValues); + } + else + { + throw new NotSupportedException(_stringLocalizer["try_agin"]); + } + } + } + } + if (res > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + else + { + return (false, _stringLocalizer["operation_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)&&t.move_status == 0).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + + /// + /// get next order code number + /// + /// + public async Task GetOrderCode(CurrentUser currentUser) + { + string code; + string date = DateTime.Now.ToString("yyyy" + "MM" + "dd"); + string maxNo = await _dBContext.GetDbSet().AsNoTracking().Where(t=>t.tenant_id == currentUser.tenant_id).MaxAsync(t => t.job_code); + if (maxNo == null) + { + code = date + "-0001"; + } + else + { + string maxDate = maxNo.Substring(0, 8); + string maxDateNo = maxNo.Substring(9, 4); + if (date == maxDate) + { + int.TryParse(maxDateNo, out int dd); + int newDateNo = dd + 1; + code = date + "-" + newDateNo.ToString("0000"); + } + else + { + code = date + "-0001"; + } + } + + return code; + } + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/Services/Stockprocess/StockprocessService.cs b/backend/ModernWMS.WMS/Services/Stockprocess/StockprocessService.cs new file mode 100644 index 0000000..79a10a8 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Stockprocess/StockprocessService.cs @@ -0,0 +1,482 @@ +/* + * date:2022-12-23 + * developer:NoNo + */ +using Mapster; +using Microsoft.EntityFrameworkCore; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using ModernWMS.Core.Models; +using ModernWMS.Core.JWT; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DynamicSearch; +using System.Linq.Expressions; +using System.Reflection; +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc.Formatters.Xml; +using Microsoft.AspNetCore.SignalR.Protocol; +using System.Linq; + +namespace ModernWMS.WMS.Services +{ + /// + /// Stockprocess Service + /// + public class StockprocessService : BaseService, IStockprocessService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Stockprocess constructor + /// + /// The DBContext + /// Localizer + public StockprocessService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet(); + var adjust_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var adjusted = from a in adjust_DBSet + join d in _dBContext.GetDbSet().AsNoTracking() on a.source_table_id equals d.id + where a.job_type == 2 + group d by d.stock_process_id into ag + select new + { + stockprocess_id = ag.Key + }; + var query = from m in DbSet.AsNoTracking() + join a in adjusted on m.id equals a.stockprocess_id into a_left + from a in a_left.DefaultIfEmpty() + select new StockprocessGetViewModel + { + id = m.id, + job_code = m.job_code, + job_type = m.job_type, + process_status = m.process_status, + processor = m.processor, + process_time = m.process_time, + creator = m.creator, + create_time = m.create_time, + last_update_time = m.last_update_time, + tenant_id = m.tenant_id, + adjust_status = (m.process_status && (a.stockprocess_id == null ? false : true)) ? true : false + }; + query = query + .Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + .Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking().Where(t => t.tenant_id.Equals(currentUser.tenant_id)).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.AsNoTracking().FirstOrDefaultAsync(t => t.id.Equals(id)); + var details = await (from spd in _dBContext.GetDbSet().AsNoTracking().Where(t => t.stock_process_id == id) + join sku in _dBContext.GetDbSet().AsNoTracking() on spd.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + join gl in _dBContext.GetDbSet().AsNoTracking() on spd.goods_location_id equals gl.id into gl_left + from gl in gl_left.DefaultIfEmpty() + select new StockprocessdetailViewModel + { + id = spd.id, + stock_process_id = spd.stock_process_id, + sku_id = spd.sku_id, + goods_owner_id = spd.goods_owner_id, + goods_location_id = spd.goods_location_id, + qty = spd.qty, + last_update_time = spd.last_update_time, + tenant_id = spd.tenant_id, + is_source = spd.is_source, + sku_code = sku.sku_code, + spu_code = spu.spu_code, + spu_name = spu.spu_name, + unit = sku.unit, + location_name = gl.location_name == null?"":gl.location_name + }).ToListAsync(); + if (entity == null) + { + return null; + } + var res = entity.Adapt(); + var adjust_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var adjusted = await (from a in adjust_DBSet + join d in _dBContext.GetDbSet().AsNoTracking() on a.source_table_id equals d.id + where a.job_type == 2 + select a + ).AnyAsync(); + res.adjust_status = adjusted; + res.source_detail_list = details.Where(t => t.is_source == true).ToList(); + res.target_detail_list = details.Where(t => t.is_source == false).ToList(); + return res; + } + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + public async Task<(int id, string msg)> AddAsync(StockprocessViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var entity = viewModel.Adapt(); + var stock_DBSet = _dBContext.GetDbSet().AsNoTracking(); + + ParameterExpression parameterExpression = Expression.Parameter(typeof(StockEntity), "m"); + Expression exp = null; + for (int i = 0; i < entity.detailList.Count; i++) + { + ConstantExpression t_constan_location = Expression.Constant(entity.detailList[i].goods_location_id); + PropertyInfo t_prop_location = typeof(StockEntity).GetProperty("goods_location_id"); + MemberExpression t_location_exp = Expression.Property(parameterExpression, t_prop_location); + BinaryExpression t_location_full_exp = Expression.Equal(t_location_exp, t_constan_location); + ConstantExpression t_constan_sku = Expression.Constant(entity.detailList[i].sku_id); + PropertyInfo t_prop_sku = typeof(StockEntity).GetProperty("sku_id"); + MemberExpression t_sku_exp = Expression.Property(parameterExpression, t_prop_sku); + BinaryExpression t_sku_full_exp = Expression.Equal(t_sku_exp, t_constan_sku); + ConstantExpression t_constan_owner = Expression.Constant(entity.detailList[i].goods_owner_id); + PropertyInfo t_prop_owner = typeof(StockEntity).GetProperty("goods_owner_id"); + MemberExpression t_owner_exp = Expression.Property(parameterExpression, t_prop_owner); + BinaryExpression t_owner_full_exp = Expression.Equal(t_owner_exp, t_constan_owner); + var t_exp = Expression.And(t_location_full_exp, t_sku_full_exp); + t_exp = Expression.And(t_exp, t_owner_full_exp); + if (exp != null) + exp = Expression.Or(exp, t_exp); + else + exp = t_exp; + } + var predicate_res = Expression.Lambda>(exp, new ParameterExpression[1] { parameterExpression }); + var stocks = await stock_DBSet.Where(predicate_res).ToListAsync(); + var goods_location_id_list = viewModel.detailList.Where(t => t.is_source == true).Select(t => t.goods_location_id).ToList(); + var sku_id_list = viewModel.detailList.Where(t => t.is_source == true).Select(t => t.sku_id).ToList(); + var lockeds = await (from d in _dBContext.GetDbSet().AsNoTracking() + where d.is_update_stock == false && goods_location_id_list.Contains(d.goods_location_id) + && sku_id_list.Contains(d.sku_id) + group d by new { d.goods_location_id, d.sku_id } into lg + select new + { + sku_id = lg.Key.sku_id, + goods_location_id = lg.Key.goods_location_id, + qty_locked = lg.Sum(e => e.qty) + }).ToListAsync(); + entity.id = 0; + entity.create_time = DateTime.Now; + entity.creator = currentUser.user_name; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + entity.job_code = await GetOrderCode(currentUser); + await DbSet.AddAsync(entity); + foreach (var d in entity.detailList) + { + d.tenant_id =currentUser.tenant_id; + d.last_update_time = DateTime.Now; + d.id = 0; + var s = stocks.FirstOrDefault(t => t.sku_id == d.sku_id && t.goods_location_id == d.goods_location_id); + if (d.is_source == true) + { + if (s == null) + { + return (0, _stringLocalizer["data_changed"]); + } + var locked = lockeds.FirstOrDefault(t => t.sku_id == d.sku_id && t.goods_location_id == d.goods_location_id); + if ((s.qty - (locked == null ? 0 : locked.qty_locked)) < d.qty) + { + return (0, _stringLocalizer["data_changed"]); + } + if (s.is_freeze == true) + { + return (0, _stringLocalizer["stock_frozen"]); + } + } + } + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// + public async Task<(bool flag, string msg)> UpdateAsync(StockprocessViewModel viewModel) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + entity.id = viewModel.id; + entity.job_code = viewModel.job_code; + entity.job_type = viewModel.job_type; + entity.process_status = viewModel.process_status; + entity.processor = viewModel.processor; + entity.process_time = viewModel.process_time; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var entity = await _dBContext.GetDbSet().Where(t => t.id.Equals(id) && t.process_status == false).Include(e => e.detailList).FirstOrDefaultAsync(); + _dBContext.GetDbSet().Remove(entity); + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + + /// + /// confirm adjustment + /// + /// id + /// current user + /// + public async Task<(bool flag, string msg)> ConfirmAdjustment(int id, CurrentUser currentUser) + { + var DBSet = _dBContext.GetDbSet(); + var entity = await DBSet.FirstOrDefaultAsync(t => t.id == id); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + var detail_DBSet = _dBContext.GetDbSet(); + var adjust_DBset = _dBContext.GetDbSet(); + var details = await detail_DBSet.Where(t => t.stock_process_id == id).ToListAsync(); + var adjusts = (from d in details + select new StockadjustEntity + { + sku_id = d.sku_id, + source_table_id = d.id, + is_update_stock = true, + goods_location_id = d.goods_location_id, + job_type = 2, + goods_owner_id = d.goods_owner_id, + qty = d.is_source ? -d.qty : d.qty, + create_time = DateTime.Now, + creator = currentUser.user_name, + last_update_time = DateTime.Now, + tenant_id = currentUser.tenant_id, + }).ToList(); + entity.last_update_time = DateTime.Now; + var stock_DBSet = _dBContext.GetDbSet(); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + + var stocks = await stock_DBSet.Where(s => detail_DBSet.Where(t => t.stock_process_id == id).Any(t => t.goods_location_id == s.goods_location_id && t.sku_id == s.sku_id && t.goods_owner_id == s.goods_owner_id)).ToListAsync(); + foreach (var d in details) + { + var stock = stocks.FirstOrDefault(t => t.goods_location_id == d.goods_location_id && t.sku_id == d.sku_id && t.goods_owner_id == d.goods_owner_id); + d.is_update_stock= true; + d.last_update_time = DateTime.Now; + if (d.is_source) + { + if (stock == null) + { + return (false, _stringLocalizer["data_changed"]); + } + stock.qty -= d.qty; + stock.last_update_time = DateTime.Now; + } + else + { + if(stock == null) + { + await stock_DBSet.AddAsync(new StockEntity + { + sku_id= d.sku_id, + goods_location_id= d.goods_location_id, + goods_owner_id= d.goods_owner_id, + is_freeze =false, + last_update_time =DateTime.Now, + qty= d.qty, + tenant_id = currentUser.tenant_id + }); + } + else + { + stock.qty += d.qty; + stock.last_update_time = DateTime.Now; + } + } + } + var code = await GetAdjustOrderCode(currentUser); + adjusts.ForEach(t => t.job_code = code); + await adjust_DBset.AddRangeAsync(adjusts); + var res = await _dBContext.SaveChangesAsync(); + if (res > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + return (false, _stringLocalizer["operation_failed"]); + } + + /// + /// confirm processing + /// + /// id + /// + public async Task<(bool flag, string msg)> ConfirmProcess(int id, CurrentUser currentUser) + { + var DBSet = _dBContext.GetDbSet(); + var entity = await DBSet.FirstOrDefaultAsync(t => t.id == id); + entity.process_status = true; + entity.processor = currentUser.user_name; + entity.process_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + var res = await _dBContext.SaveChangesAsync(); + if (res > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + return (false, _stringLocalizer["operation_failed"]); + } + + /// + /// get next order code number + /// + /// + public async Task GetOrderCode(CurrentUser currentUser) + { + string code; + string date = DateTime.Now.ToString("yyyy" + "MM" + "dd"); + string maxNo = await _dBContext.GetDbSet().AsNoTracking().Where(t=>t.tenant_id == currentUser.tenant_id).MaxAsync(t => t.job_code); + if (maxNo == null) + { + code = date + "-0001"; + } + else + { + string maxDate = maxNo.Substring(0, 8); + string maxDateNo = maxNo.Substring(9, 4); + if (date == maxDate) + { + int.TryParse(maxDateNo, out int dd); + int newDateNo = dd + 1; + code = date + "-" + newDateNo.ToString("0000"); + } + else + { + code = date + "-0001"; + } + } + + return code; + } + /// + /// get next order code number + /// + /// + public async Task GetAdjustOrderCode(CurrentUser currentUser) + { + string code; + string date = DateTime.Now.ToString("yyyy" + "MM" + "dd"); + string maxNo = await _dBContext.GetDbSet().AsNoTracking().Where(t => t.tenant_id == currentUser.tenant_id).MaxAsync(t => t.job_code); + if (maxNo == null) + { + code = date + "-0001"; + } + else + { + string maxDate = maxNo.Substring(0, 8); + string maxDateNo = maxNo.Substring(9, 4); + if (date == maxDate) + { + int.TryParse(maxDateNo, out int dd); + int newDateNo = dd + 1; + code = date + "-" + newDateNo.ToString("0000"); + } + else + { + code = date + "-0001"; + } + } + + return code; + } + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/Services/Stocktaking/StocktakingService.cs b/backend/ModernWMS.WMS/Services/Stocktaking/StocktakingService.cs new file mode 100644 index 0000000..35e01b9 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Stocktaking/StocktakingService.cs @@ -0,0 +1,363 @@ +/* + * date:2022-12-30 + * developer:AMo + */ + using Mapster; + using Microsoft.EntityFrameworkCore; + using ModernWMS.Core.DBContext; + using ModernWMS.Core.Services; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; + using ModernWMS.Core.DynamicSearch; +using ModernWMS.Core.Models; +using ModernWMS.Core.JWT; +using System.Linq; + +namespace ModernWMS.WMS.Services +{ + /// + /// Stocktaking Service + /// + public class StocktakingService : BaseService, IStocktakingService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Stocktaking constructor + /// + /// The DBContext + /// Localizer + public StocktakingService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var Stocktakings = _dBContext.GetDbSet(); + var Spus = _dBContext.GetDbSet(); + var Skus = _dBContext.GetDbSet(); + var Goodsowners = _dBContext.GetDbSet(); + var Goodslocations = _dBContext.GetDbSet(); + var Stockadjusts = _dBContext.GetDbSet(); + var queryAdjust = Stockadjusts.AsNoTracking().Where(t => t.job_type == 1).Select(t => new { t.id, t.source_table_id }); + + var query = from st in Stocktakings.AsNoTracking() + join sku in Skus.AsNoTracking() on st.sku_id equals sku.id + join spu in Spus.AsNoTracking() on sku.spu_id equals spu.id + join gsl in Goodslocations.AsNoTracking() on st.goods_location_id equals gsl.id + join gso in Goodsowners.AsNoTracking() on st.goods_owner_id equals gso.id into gsoJoin + from gso in gsoJoin.DefaultIfEmpty() + join adj in queryAdjust on st.id equals adj.source_table_id into adjJoin + from adj in adjJoin.DefaultIfEmpty() + where st.tenant_id == currentUser.tenant_id + select new StocktakingViewModel + { + id = st.id, + job_code = st.job_code, + job_status = st.job_status, + adjust_status = adj.id == null ? false : true, + sku_id = sku.id, + sku_code = sku.sku_code, + sku_name = sku.sku_name, + spu_code = spu.spu_code, + spu_name = spu.spu_name, + goods_location_id = st.goods_location_id, + warehouse_name = gsl.warehouse_name, + location_name = gsl.location_name, + goods_owner_id = st.goods_owner_id, + goods_owner_name = gso.goods_owner_name == null ? string.Empty : gso.goods_owner_name, + book_qty = st.book_qty, + counted_qty = st.counted_qty, + difference_qty = st.difference_qty, + creator = st.creator, + create_time = st.create_time, + handler = st.handler, + handle_time = st.handle_time, + last_update_time = st.last_update_time + }; + query = query.Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var Stocktakings = _dBContext.GetDbSet(); + var Spus = _dBContext.GetDbSet(); + var Skus = _dBContext.GetDbSet(); + var Goodsowners = _dBContext.GetDbSet(); + var Goodslocations = _dBContext.GetDbSet(); + var Stockadjusts = _dBContext.GetDbSet(); + var queryAdjust = Stockadjusts.AsNoTracking().Where(t => t.job_type == 1).Select(t => new { t.id, t.source_table_id }); + + var query = from st in Stocktakings.AsNoTracking() + join sku in Skus.AsNoTracking() on st.sku_id equals sku.id + join spu in Spus.AsNoTracking() on sku.spu_id equals spu.id + join gsl in Goodslocations.AsNoTracking() on st.goods_location_id equals gsl.id + join gso in Goodsowners.AsNoTracking() on st.goods_owner_id equals gso.id into gsoJoin + from gso in gsoJoin.DefaultIfEmpty() + join adj in queryAdjust on st.id equals adj.source_table_id into adjJoin + from adj in adjJoin.DefaultIfEmpty() + where st.id == id + select new StocktakingViewModel + { + id = st.id, + job_code = st.job_code, + job_status = st.job_status, + adjust_status = adj.id == null ? false : true, + sku_id = sku.id, + sku_code = sku.sku_code, + sku_name = sku.sku_name, + spu_code = spu.spu_code, + spu_name = spu.spu_name, + goods_location_id = st.goods_location_id, + warehouse_name = gsl.warehouse_name, + location_name = gsl.location_name, + goods_owner_id = st.goods_owner_id, + goods_owner_name = gso.goods_owner_name == null ? string.Empty : gso.goods_owner_name, + book_qty = st.book_qty, + counted_qty = st.counted_qty, + difference_qty = st.difference_qty, + creator = st.creator, + create_time = st.create_time, + handler = st.handler, + handle_time = st.handle_time, + last_update_time = st.last_update_time + }; + var data = await query.FirstOrDefaultAsync(); + if (data != null) + { + return data; + } + else + { + return new StocktakingViewModel(); + } + } + /// + /// add a new record + /// + /// viewmodel + /// currentUser + /// + public async Task<(int id, string msg)> AddAsync(StocktakingBasicViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var entity = viewModel.Adapt(); + entity.id = 0; + entity.job_code = await GetOrderCode(currentUser); + entity.creator = currentUser.user_name; + entity.create_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + + /// + /// get next code number + /// + /// currentUser + /// + public async Task GetOrderCode(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + string code = ""; + string date = DateTime.Now.ToString("yyyy" + "MM" + "dd"); + string maxNo = await DbSet.AsNoTracking().Where(t => t.tenant_id.Equals(currentUser.tenant_id)).MaxAsync(t => t.job_code); + if (string.IsNullOrEmpty(maxNo)) + { + code = date + "-0001"; + } + else + { + try + { + string maxDate = maxNo[..8]; + string maxDateNo = maxNo[9..]; + if (date == maxDate) + { + int.TryParse(maxDateNo, out int dd); + int newDateNo = dd + 1; + code = date + "-" + newDateNo.ToString("0000"); + } + else + { + code = date + "-0001"; + } + } + catch + { + code = date + "-0001"; + } + } + + return code; + } + /// + /// update counted_qty + /// + /// args + /// currentUser + /// + public async Task<(bool flag, string msg)> PutAsync(StocktakingConfirmViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + entity.counted_qty = viewModel.counted_qty; + entity.difference_qty = viewModel.counted_qty - entity.book_qty; + entity.last_update_time = DateTime.Now; + entity.handler = currentUser.user_name; + entity.handle_time = DateTime.Now; + entity.job_status = true; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + + /// + /// Confirm a record + /// + /// id + /// currentUser + /// + public async Task<(bool flag, string msg)> ConfirmAsync(int id, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + // change stock sku qty + var Stocks = _dBContext.GetDbSet(); + var stockEntity = await Stocks.FirstOrDefaultAsync(t => t.sku_id.Equals(entity.sku_id) + && t.goods_owner_id.Equals(entity.goods_owner_id) + && t.goods_location_id.Equals(entity.goods_location_id)); + if (stockEntity == null) + { + await Stocks.AddAsync(new StockEntity + { + sku_id = entity.sku_id, + goods_location_id = entity.goods_location_id, + qty = entity.difference_qty, + goods_owner_id = entity.goods_owner_id, + is_freeze = false, + last_update_time = DateTime.Now, + tenant_id = currentUser.tenant_id + }); + } + else + { + stockEntity.qty += entity.difference_qty; + stockEntity.last_update_time = DateTime.Now; + } + // add a record to stockadjust + var Stockadjusts = _dBContext.GetDbSet(); + await Stockadjusts.AddAsync(new StockadjustEntity + { + job_code = entity.job_code, + sku_id = entity.sku_id, + goods_location_id = entity.goods_location_id, + goods_owner_id = entity.goods_owner_id, + qty = entity.difference_qty, + creator = currentUser.user_name, + create_time = DateTime.Now, + last_update_time = DateTime.Now, + tenant_id = currentUser.tenant_id, + is_update_stock = true, + job_type = 1, + source_table_id = entity.id + }); + + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["operation_success"]); + } + else + { + return (false, _stringLocalizer["operation_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/Services/Warehouse/WarehouseService.cs b/backend/ModernWMS.WMS/Services/Warehouse/WarehouseService.cs new file mode 100644 index 0000000..35cdce7 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Warehouse/WarehouseService.cs @@ -0,0 +1,284 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using Mapster; +using Microsoft.EntityFrameworkCore; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using ModernWMS.Core.Models; +using ModernWMS.Core.JWT; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DynamicSearch; +using System.Text; + +namespace ModernWMS.WMS.Services +{ + /// + /// Warehouse Service + /// + public class WarehouseService : BaseService, IWarehouseService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Warehouse constructor + /// + /// The DBContext + /// Localizer + public WarehouseService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// get select items + /// + /// current user + /// + public async Task> GetSelectItemsAsnyc(CurrentUser currentUser) + { + var res = new List(); + var DBSet = _dBContext.GetDbSet(); + res.AddRange(await (from db in DBSet.AsNoTracking() + where db.is_valid == true && db.tenant_id == currentUser.tenant_id + select new FormSelectItem + { + code = "warehouse_name", + name = db.warehouse_name, + value = db.id.ToString(), + comments = "warehouse datas", + }).ToListAsync()); + return res; + } + + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet(); + var query = DbSet.AsNoTracking() + .Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + .Where(queries.AsExpression()); + if (pageSearch.sqlTitle == "select") + { + query = query.Where(t => t.is_valid == true); + } + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list.Adapt>(), totals); + } + + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking().Where(t => t.tenant_id.Equals(currentUser.tenant_id)).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.AsNoTracking().FirstOrDefaultAsync(t => t.id.Equals(id)); + if (entity == null) + { + return null; + } + return entity.Adapt(); + } + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + public async Task<(int id, string msg)> AddAsync(WarehouseViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.warehouse_name == viewModel.warehouse_name && t.tenant_id == currentUser.tenant_id)) + { + return(0, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["warehouse_name"], viewModel.warehouse_name)); + } + var entity = viewModel.Adapt(); + entity.id = 0; + entity.create_time = DateTime.Now; + entity.creator = currentUser.user_name; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// currentUser + /// + public async Task<(bool flag, string msg)> UpdateAsync(WarehouseViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.id != viewModel.id && t.warehouse_name == viewModel.warehouse_name && t.tenant_id == currentUser.tenant_id)) + { + return(false, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["warehouse_name"], viewModel.warehouse_name)); + } + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + entity.id = viewModel.id; + entity.warehouse_name = viewModel.warehouse_name; + entity.city = viewModel.city; + entity.address = viewModel.address; + entity.email = viewModel.email; + entity.manager = viewModel.manager; + entity.contact_tel = viewModel.contact_tel; + entity.is_valid = viewModel.is_valid; + entity.last_update_time = DateTime.Now; + var warehousearea_DBSet = _dBContext.GetDbSet(); + var wadatas =await warehousearea_DBSet.Where(t => t.warehouse_id == entity.id).ToListAsync(); + wadatas.ForEach(t => + { + t.is_valid = entity.is_valid; + }); + var goodslocation_DBSet = _dBContext.GetDbSet(); + var gldatas = await goodslocation_DBSet.Where(t => t.warehouse_area_id == entity.id).ToListAsync(); + gldatas.ForEach(t => + { + t.warehouse_name = entity.warehouse_name; + t.is_valid = entity.is_valid; + }); + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + if (await _dBContext.GetDbSet().AnyAsync(t => t.warehouse_id == id)) + { + return (false, _stringLocalizer["exist_warehousearea_not_delete"]); + } + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + + /// + /// import warehouses by excel + /// + /// excel datas + /// current user + /// + public async Task<(bool flag, string msg)> ExcelAsync(List datas, CurrentUser currentUser) + { + StringBuilder sb = new StringBuilder(); + var DbSet = _dBContext.GetDbSet(); + var warehouse_name_repeat_excel = datas.GroupBy(t => t.warehouse_name).Select(t => new { warehouse_name = t.Key, cnt = t.Count() }).Where(t => t.cnt > 1).ToList(); + foreach (var repeat in warehouse_name_repeat_excel) + { + sb.AppendLine(string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["warehouse_name"], repeat.warehouse_name)); + } + if (warehouse_name_repeat_excel.Count > 0) + { + return (false, sb.ToString()); + } + + var warehouse_name_repeat_exists = await DbSet.Where(t=>t.tenant_id == currentUser.tenant_id).Where(t => datas.Select(t => t.warehouse_name).ToList().Contains(t.warehouse_name)).Select(t => t.warehouse_name).ToListAsync(); + foreach (var repeat in warehouse_name_repeat_exists) + { + sb.AppendLine(string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["warehouse_name"], repeat)); + } + if (warehouse_name_repeat_exists.Count > 0) + { + return (false, sb.ToString()); + } + + var entities = datas.Adapt>(); + entities.ForEach(t => + { + t.creator = currentUser.user_name; + t.tenant_id = currentUser.tenant_id; + t.create_time = DateTime.Now; + t.last_update_time = DateTime.Now; + t.is_valid = true; + }); + await DbSet.AddRangeAsync(entities); + var res = await _dBContext.SaveChangesAsync(); + if (res > 0) + { + return (true, _stringLocalizer["save_success"]); + } + return (false, _stringLocalizer["save_failed"]); + } + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/Services/Warehousearea/WarehouseareaService.cs b/backend/ModernWMS.WMS/Services/Warehousearea/WarehouseareaService.cs new file mode 100644 index 0000000..0ce7419 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/Warehousearea/WarehouseareaService.cs @@ -0,0 +1,248 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ +using Mapster; +using Microsoft.EntityFrameworkCore; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using ModernWMS.Core.Models; +using ModernWMS.Core.JWT; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DynamicSearch; +using Microsoft.EntityFrameworkCore.Query.SqlExpressions; +using System.Net.WebSockets; + +namespace ModernWMS.WMS.Services +{ + /// + /// Warehousearea Service + /// + public class WarehouseareaService : BaseService, IWarehouseareaService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Warehousearea constructor + /// + /// The DBContext + /// Localizer + public WarehouseareaService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet(); + var warehouse_DBSet = _dBContext.GetDbSet(); + + var query = from wa in DbSet.AsNoTracking() + join w in warehouse_DBSet.AsNoTracking() on wa.warehouse_id equals w.id + select new WarehouseareaViewModel + { + id = wa.id, + warehouse_id = wa.warehouse_id, + warehouse_name = w.warehouse_name, + area_name = wa.area_name, + parent_id = wa.parent_id, + create_time = wa.create_time, + last_update_time = wa.last_update_time, + is_valid = wa.is_valid, + tenant_id = wa.tenant_id, + area_property = wa.area_property, + }; + if (pageSearch.sqlTitle == "select") + { + query = query.Where(t => t.is_valid == true); + } + query = query.Where(t => t.tenant_id.Equals(currentUser.tenant_id)).Where(queries.AsExpression()); + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list, totals); + } + /// + /// get warehouseareas of the warehouse by warehouse_id + /// + /// warehouse's id + /// current user + /// + public async Task> GetWarehouseareaByWarehouse_id(int warehouse_id, CurrentUser currentUser) + { + var res = new List(); + var DbSet = _dBContext.GetDbSet(); + res = await (from wa in DbSet.AsNoTracking() + where wa.is_valid == true && wa.tenant_id == currentUser.tenant_id && wa.warehouse_id == warehouse_id + select new FormSelectItem + { + code = "warehousearea", + comments = "warehouseareas of the warehouse", + name = wa.area_name, + value = wa.id.ToString(), + }).ToListAsync(); + return res; + } + + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(int warehouse_id, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet().AsNoTracking(); + if (warehouse_id > 0) + { + DbSet = DbSet.Where(t=>t.warehouse_id == warehouse_id); + } + var data = await DbSet.Where(t =>t.is_valid == true && t.tenant_id.Equals(currentUser.tenant_id)).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.AsNoTracking().FirstOrDefaultAsync(t => t.id.Equals(id)); + if (entity == null) + { + return null; + } + return entity.Adapt(); + } + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + public async Task<(int id, string msg)> AddAsync(WarehouseareaViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.warehouse_id == viewModel.warehouse_id && t.area_name == viewModel.area_name && t.tenant_id == currentUser.tenant_id)) + { + return (0, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["area_name"], viewModel.area_name)); + } + var entity = viewModel.Adapt(); + entity.id = 0; + entity.create_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// currentUser + /// + public async Task<(bool flag, string msg)> UpdateAsync(WarehouseareaViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (await DbSet.AnyAsync(t => t.id != viewModel.id && t.warehouse_id == viewModel.warehouse_id && t.area_name == viewModel.area_name && t.tenant_id == currentUser.tenant_id)) + { + return (false, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["area_name"], viewModel.area_name)); + } + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + entity.id = viewModel.id; + entity.warehouse_id = viewModel.warehouse_id; + entity.area_name = viewModel.area_name; + entity.parent_id = viewModel.parent_id; + entity.is_valid = viewModel.is_valid; + entity.area_property = viewModel.area_property; + entity.last_update_time = DateTime.Now; + var goodslocation_DBSet = _dBContext.GetDbSet(); + var gldatas = await goodslocation_DBSet.Where(t => t.warehouse_area_id == entity.id).ToListAsync(); + gldatas.ForEach(t => + { + t.warehouse_area_name = entity.area_name; + t.warehouse_area_property = entity.area_property; + t.is_valid = entity.is_valid; + }); + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + if (await _dBContext.GetDbSet < GoodslocationEntity>().AnyAsync(t=>t.warehouse_area_id == id)) + { + return (false, _stringLocalizer["exist_location_not_delete"]); + } + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/Services/company/CompanyService.cs b/backend/ModernWMS.WMS/Services/company/CompanyService.cs new file mode 100644 index 0000000..095819c --- /dev/null +++ b/backend/ModernWMS.WMS/Services/company/CompanyService.cs @@ -0,0 +1,159 @@ +using Mapster; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.JWT; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; + +namespace ModernWMS.WMS.Services +{ + /// + /// CompanyService + /// + public class CompanyService : BaseService, ICompanyService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localization + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + /// company service constructor + /// + /// The DBContext + /// Localization + public CompanyService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking().Where(t => t.tenant_id == currentUser.tenant_id) + .OrderByDescending(t => t.create_time) + .ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// id + /// + public async Task GetAsync(int id) + { + var entity = await _dBContext.GetDbSet().AsNoTracking().FirstOrDefaultAsync(t => t.id.Equals(id)); + if (entity != null) + { + return entity.Adapt(); + } + else + { + return new CompanyViewModel(); + } + } + /// + /// add a new record + /// + /// args + /// currentUser + /// + public async Task<(int id, string msg)> AddAsync(CompanyViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.tenant_id.Equals(currentUser.tenant_id) && t.company_name.Equals(viewModel.company_name))) + { + return (0, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["company_name"], viewModel.company_name)); + } + var entity = viewModel.Adapt(); + entity.id = 0; + entity.create_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + DbSet.Add(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// + public async Task<(bool flag, string msg)> UpdateAsync(CompanyViewModel viewModel) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + if (await DbSet.AnyAsync(t => !t.id.Equals(viewModel.id) && t.tenant_id.Equals(entity.tenant_id) && t.company_name.Equals(viewModel.company_name))) + { + //国际化 + return (false, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["company_name"], viewModel.company_name)); + } + entity.company_name = viewModel.company_name; + entity.city = viewModel.city; + entity.address = viewModel.address; + entity.manager = viewModel.manager; + entity.contact_tel = viewModel.contact_tel; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Services/supplier/SupplierService.cs b/backend/ModernWMS.WMS/Services/supplier/SupplierService.cs new file mode 100644 index 0000000..620fcd0 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/supplier/SupplierService.cs @@ -0,0 +1,246 @@ +/* + * date:2022-12-21 + * developer:NoNo + */ + using Mapster; + using Microsoft.EntityFrameworkCore; + using ModernWMS.Core.DBContext; + using ModernWMS.Core.Services; + using ModernWMS.WMS.Entities.Models; + using ModernWMS.WMS.Entities.ViewModels; + using ModernWMS.WMS.IServices; + using Microsoft.Extensions.Localization; + using ModernWMS.Core.DynamicSearch; +using ModernWMS.Core.Models; +using ModernWMS.Core.JWT; +using ModernWMS.Core.Utility; +using System.Text; + +namespace ModernWMS.WMS.Services + { + /// + /// Supplier Service + /// + public class SupplierService : BaseService, ISupplierService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Supplier constructor + /// + /// The DBContext + /// Localizer + public SupplierService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer= stringLocalizer; + } + #endregion + + #region Api + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet(); + var query = DbSet.AsNoTracking() + .Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + .Where(queries.AsExpression()); + if(pageSearch.sqlTitle == "select") + { + query = query.Where(t => t.is_valid == true); + } + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list.Adapt>(), totals); + } + + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking().Where(t=>t.tenant_id.Equals(currentUser.tenant_id)).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.AsNoTracking().FirstOrDefaultAsync(t=>t.id.Equals(id)); + if (entity == null) + { + return null; + } + return entity.Adapt(); + } + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + public async Task<(int id, string msg)> AddAsync(SupplierViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var entity = viewModel.Adapt(); + entity.id = 0; + entity.create_time = DateTime.Now; + entity.creator = currentUser.user_name; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + await DbSet.AddAsync(entity); + if (await DbSet.AnyAsync(t => t.supplier_name == viewModel.supplier_name && t.tenant_id == currentUser.tenant_id)) + { + return (0, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["supplier_name"], viewModel.supplier_name)); + } + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// currentUser + /// + public async Task<(bool flag, string msg)> UpdateAsync(SupplierViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.id != viewModel.id && t.supplier_name == viewModel.supplier_name && t.tenant_id == currentUser.tenant_id)) + { + return(false, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["supplier_name"], viewModel.supplier_name)); + } + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false,_stringLocalizer[ "not_exists_entity"]); + } + entity.id = viewModel.id; + entity.supplier_name = viewModel.supplier_name; + entity.city = viewModel.city; + entity.address = viewModel.address; + entity.email = viewModel.email; + entity.manager = viewModel.manager; + entity.contact_tel = viewModel.contact_tel; + entity.is_valid = viewModel.is_valid; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + + /// + /// import suppliers by excel + /// + /// excel datas + /// current user + /// + public async Task<(bool flag, string msg)> ExcelAsync(List datas,CurrentUser currentUser) + { + StringBuilder sb = new StringBuilder(); + var DbSet = _dBContext.GetDbSet(); + var supplier_name_repeat_excel = datas.GroupBy(t => t.supplier_name).Select(t => new { supplier_name = t.Key, cnt = t.Count() }).Where(t => t.cnt > 1).ToList(); + foreach (var repeat in supplier_name_repeat_excel) + { + sb.AppendLine(string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["supplier_name"], repeat.supplier_name)); + } + if (supplier_name_repeat_excel.Count > 0) + { + return (false, sb.ToString()); + } + + var supplier_name_repeat_exists = await DbSet.Where(t=>t.tenant_id == currentUser.tenant_id).Where(t => datas.Select(t => t.supplier_name).ToList().Contains(t.supplier_name)).Select(t => t.supplier_name).ToListAsync(); + foreach (var repeat in supplier_name_repeat_exists) + { + sb.AppendLine(string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["supplier_name"], repeat)); + } + if (supplier_name_repeat_exists.Count > 0) + { + return (false, sb.ToString()); + } + + var entities = datas.Adapt>(); + entities.ForEach(t => { + t.creator = currentUser.user_name; + t.tenant_id = currentUser.tenant_id; + t.create_time = DateTime.Now; + t.last_update_time = DateTime.Now; + t.is_valid = true; + }); + await DbSet.AddRangeAsync(entities); + var res = await _dBContext.SaveChangesAsync(); + if (res > 0) + { + return (true, _stringLocalizer["save_success"]); + } + return (false, _stringLocalizer["save_failed"]); + } + #endregion + } + } + diff --git a/backend/ModernWMS.WMS/Services/user/UserService.cs b/backend/ModernWMS.WMS/Services/user/UserService.cs new file mode 100644 index 0000000..acb0b6d --- /dev/null +++ b/backend/ModernWMS.WMS/Services/user/UserService.cs @@ -0,0 +1,560 @@ +/* + * date:2022-12-20 + * developer:NoNo + */ +using Mapster; +using Microsoft.EntityFrameworkCore; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using ModernWMS.Core.Models; +using Microsoft.Extensions.Localization; +using ModernWMS.Core.Utility; +using System.Text; +using ModernWMS.Core.JWT; +using ModernWMS.Core.DynamicSearch; +using Microsoft.AspNetCore.Components.Forms; +using System.ComponentModel.Design; + +namespace ModernWMS.WMS.Services +{ + /// + /// User Service + /// + public class UserService : BaseService, IUserService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///User constructor + /// + /// The DBContext + /// Localizer + public UserService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// get select items + /// + /// current user + /// + public async Task> GetSelectItemsAsnyc(CurrentUser currentUser) + { + var res = new List(); + var userrole_DBSet = _dBContext.GetDbSet(); + res.AddRange(await (from ur in userrole_DBSet.AsNoTracking() + where ur.is_valid == true && ur.tenant_id == currentUser.tenant_id + select new FormSelectItem + { + code = "user_role", + name = ur.role_name, + value = ur.id.ToString(), + comments = "user's role", + }).ToListAsync()); + return res; + } + + /// + /// page search + /// + /// args + /// currentUser + /// + public async Task<(List data, int totals)> PageAsync(PageSearch pageSearch, CurrentUser currentUser) + { + QueryCollection queries = new QueryCollection(); + if (pageSearch.searchObjects.Any()) + { + pageSearch.searchObjects.ForEach(s => + { + queries.Add(s); + }); + } + var DbSet = _dBContext.GetDbSet(); + var query = DbSet.AsNoTracking() + .Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + .Where(queries.AsExpression()); + if (pageSearch.sqlTitle == "select") + { + query = query.Where(t => t.is_valid == true); + } + int totals = await query.CountAsync(); + var list = await query.OrderByDescending(t => t.create_time) + .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) + .Take(pageSearch.pageSize) + .ToListAsync(); + return (list.Adapt>(), totals); + } + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking().Where(t=>t.tenant_id == currentUser.tenant_id).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.AsNoTracking().FirstOrDefaultAsync(t => t.id.Equals(id)); + if (entity == null) + { + return null; + } + return entity.Adapt(); + } + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + public async Task<(int id, string msg)> AddAsync(UserViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.user_num == viewModel.user_num && t.tenant_id == currentUser.tenant_id)) + { + return (0, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["user_num"], viewModel.user_num)); + } + var entity = viewModel.Adapt(); + entity.id = 0; + entity.auth_string = Md5Helper.Md5Encrypt32("pwd123456"); + entity.create_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// currentUser + /// + public async Task<(bool flag, string msg)> UpdateAsync(UserViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.id != viewModel.id && t.user_num == viewModel.user_num && t.tenant_id == currentUser.tenant_id)) + { + return (false, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["user_num"], viewModel.user_num)); + } + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + entity.id = viewModel.id; + entity.user_num = viewModel.user_num; + entity.user_name = viewModel.user_name; + entity.contact_tel = viewModel.contact_tel; + entity.user_role = viewModel.user_role; + entity.sex = viewModel.sex; + entity.is_valid = viewModel.is_valid; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + /// + /// import users by excel + /// + /// excel datas + /// current user + /// + public async Task<(bool flag,string msg)>ExcelAsync(List datas,CurrentUser currentUser) + { + StringBuilder sb = new StringBuilder(); + var DbSet = _dBContext.GetDbSet(); + var user_num_repeat_excel = datas.GroupBy(t => t.user_num).Select(t=>new { user_num= t.Key,cnt = t.Count()}).Where(t=>t.cnt>1).ToList(); + foreach(var repeat in user_num_repeat_excel) + { + sb.AppendLine(string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["user_num"], repeat.user_num)); + } + if (user_num_repeat_excel.Count > 0) + { + return (false,sb.ToString()); + } + + var user_num_repeat_exists =await DbSet.Where(t=>t.tenant_id == currentUser.tenant_id).Where(t => datas.Select(t => t.user_num).ToList().Contains(t.user_num)).Select(t=>t.user_num).ToListAsync(); + foreach (var repeat in user_num_repeat_exists) + { + sb.AppendLine(string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["user_num"], repeat)); + } + if (user_num_repeat_exists.Count > 0) + { + return (false, sb.ToString()); + } + + var entities = datas.Adapt>(); + entities.ForEach(t => { + t.creator = currentUser.user_name; + t.tenant_id= currentUser.tenant_id; + t.auth_string = Md5Helper.Md5Encrypt32("pwd123456"); + t.create_time = DateTime.Now; + t.last_update_time= DateTime.Now; + t.is_valid = true; + }); + await DbSet.AddRangeAsync(entities); + var res = await _dBContext.SaveChangesAsync(); + if (res > 0) + { + return (true, _stringLocalizer["save_success"]); + } + return (false, _stringLocalizer["save_failed"]); + } + + /// + /// reset password + /// + /// viewmodel + /// + public async Task<(bool,string)> ResetPwd(BatchOperationViewModel viewModel) + { + var DBSet = _dBContext.GetDbSet(); + var entities =await DBSet.Where(t => viewModel.id_list.Contains(t.id)).ToListAsync(); + var newpassword = GetRandomPassword(); + entities.ForEach(t => { t.auth_string = Md5Helper.Md5Encrypt32(newpassword); t.last_update_time = DateTime.Now; }); + var res = await _dBContext.SaveChangesAsync(); + if (res > 0) + { + return (true, newpassword); + } + return (false,_stringLocalizer["operation_failed"]); + } + + /// + /// change password + /// + /// viewmodel + /// + public async Task<(bool flag,string msg)> ChangePwd(UserChangePwdViewModel viewModel) + { + var DBSet = _dBContext.GetDbSet(); + var entity =await DBSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if(entity == null) + { + return (false, _stringLocalizer["not_exists_entity"]); + } + if (!entity.auth_string.Equals(viewModel.old_password)){ + return(false, _stringLocalizer["old_password"] + _stringLocalizer["is_incorrect"]); + } + entity.auth_string = viewModel.new_password; + await _dBContext.SaveChangesAsync(); + return (true, _stringLocalizer["save_success"]); + } + /// + /// register a new tenant + /// + /// viewModel + /// + public async Task<(bool flag, string msg)> Register(RegisterViewModel viewModel) + { + var DbSet = _dBContext.GetDbSet(); + var entity = viewModel.Adapt(); + var time = DateTime.Now; + entity.user_num = entity.user_name; + entity.id = 0; + entity.auth_string = viewModel.auth_string; + entity.create_time = time; + entity.last_update_time = time; + entity.email = viewModel.email; + entity.sex = viewModel.sex; + entity.is_valid = true; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + var tenant_id = entity.id; + #region menus + var menus = new List + { + new MenuEntity + { + menu_name = "companySetting", + module = "baseModule", + vue_path = "companySetting", + vue_path_detail = "", + vue_directory = "base/companySetting", + sort = 1, + tenant_id = tenant_id + }, + new MenuEntity + { + menu_name = "userRoleSetting", + module = "baseModule", + vue_path = "userRoleSetting", + vue_path_detail = "", + vue_directory = "base/userRoleSetting", + sort = 2, + tenant_id = tenant_id + }, + new MenuEntity + { + menu_name = "roleMenu", + module = "baseModule", + vue_path = "roleMenu", + vue_path_detail = "", + vue_directory = "base/roleMenu", + sort = 3, + tenant_id = tenant_id + }, + new MenuEntity + { + menu_name = "userManagement", + module = "baseModule", + vue_path = "userManagement", + vue_path_detail = "", + vue_directory = "base/userManagement", + sort = 4, + tenant_id = tenant_id + }, + new MenuEntity + { + menu_name = "commodityCategorySetting", + module = "baseModule", + vue_path = "commodityCategorySetting", + vue_path_detail = "", + vue_directory = "base/commodityCategorySetting", + sort = 5, + tenant_id = tenant_id + }, + new MenuEntity + { + menu_name = "commodityManagement", + module = "baseModule", + vue_path = "commodityManagement", + vue_path_detail = "", + vue_directory = "base/commodityManagement", + sort = 6, + tenant_id = tenant_id + }, + new MenuEntity + { + menu_name = "supplier", + module = "baseModule", + vue_path = "supplier", + vue_path_detail = "", + vue_directory = "base/supplier", + sort = 7, + tenant_id = tenant_id + }, + new MenuEntity + { + menu_name = "warehouseSetting", + module = "baseModule", + vue_path = "warehouseSetting", + vue_path_detail = "", + vue_directory = "base/warehouseSetting", + sort = 8, + tenant_id = tenant_id + },new MenuEntity + { + menu_name = "ownerOfCargo", + module = "baseModule", + vue_path = "ownerOfCargo", + vue_path_detail = "", + vue_directory = "base/ownerOfCargo", + sort = 9, + tenant_id = tenant_id + },new MenuEntity + { + menu_name = "freightSetting", + module = "baseModule", + vue_path = "freightSetting", + vue_path_detail = "", + vue_directory = "base/freightSetting", + sort = 10, + tenant_id = tenant_id + },new MenuEntity + { + menu_name = "customer", + module = "baseModule", + vue_path = "customer", + vue_path_detail = "", + vue_directory = "base/customer", + sort = 11, + tenant_id = tenant_id + },new MenuEntity + { + menu_name = "stockManagement", + module = "", + vue_path = "stockManagement", + vue_path_detail = "", + vue_directory = "wms/stockManagement", + sort = 3, + tenant_id = tenant_id + },new MenuEntity + { + menu_name = "warehouseProcessing", + module = "warehouseWorkingModule", + vue_path = "warehouseProcessing", + vue_path_detail = "", + vue_directory = "warehouseWorking/warehouseProcessing", + sort = 4, + tenant_id = tenant_id + },new MenuEntity + { + menu_name = "warehouseMove", + module = "warehouseWorkingModule", + vue_path = "warehouseMove", + vue_path_detail = "", + vue_directory = "warehouseWorking/warehouseMove", + sort = 5, + tenant_id = tenant_id + },new MenuEntity + { + menu_name = "warehouseFreeze", + module = "warehouseWorkingModule", + vue_path = "warehouseFreeze", + vue_path_detail = "", + vue_directory = "warehouseWorking/warehouseFreeze", + sort = 6, + tenant_id = tenant_id + },new MenuEntity + { + menu_name = "warehouseAdjust", + module = "warehouseWorkingModule", + vue_path = "warehouseAdjust", + vue_path_detail = "", + vue_directory = "warehouseWorking/warehouseAdjust", + sort = 7, + tenant_id = tenant_id + },new MenuEntity + { + menu_name = "warehouseTaking", + module = "warehouseWorkingModule", + vue_path = "warehouseTaking", + vue_path_detail = "", + vue_directory = "warehouseWorking/warehouseTaking", + sort = 8, + tenant_id = tenant_id + },new MenuEntity + { + menu_name = "stockAsn", + module = "", + vue_path = "stockAsn", + vue_path_detail = "", + vue_directory = "wms/stockAsn", + sort = 2, + tenant_id = tenant_id + },new MenuEntity + { + menu_name = "deliveryManagement", + module = "", + vue_path = "deliveryManagement", + vue_path_detail = "", + vue_directory = "deliveryManagement/deliveryManagement", + sort = 5, + tenant_id = tenant_id + } + }; + #endregion + entity.tenant_id = tenant_id; + entity.creator = entity.user_name; + entity.user_role = "admin"; + var adminrole = new UserroleEntity {is_valid = true, last_update_time = time, create_time = time, role_name = "admin", tenant_id = tenant_id }; + await _dBContext.GetDbSet().AddAsync(adminrole); + await _dBContext.GetDbSet().AddRangeAsync(menus); + await _dBContext.SaveChangesAsync(); + foreach(var menu in menus) + { + await _dBContext.GetDbSet().AddAsync(new RolemenuEntity + { + userrole_id = adminrole.id, + authority = 1, + menu_id = menu.id, + tenant_id = tenant_id, + last_update_time=time, + create_time = time, + }); + } + await _dBContext.SaveChangesAsync(); + return (true, _stringLocalizer["operation_success"]); + } + else + { + return (false, _stringLocalizer["operation_failed"]); + } + } + + /// + /// get a random password + /// + /// + public string GetRandomPassword() + { + string randomChars = "ABCDEFGHIJKLMNOPQRSTVWXYZ123456789"; + string password = string.Empty; + int randomNum; + Random random = new Random(); + for (int i = 0; i < 6; i++) + { + randomNum = random.Next(randomChars.Length); + password += randomChars[randomNum]; + } + return password; + } + + #endregion + } +} + diff --git a/backend/ModernWMS.WMS/Services/userrole/UserroleService.cs b/backend/ModernWMS.WMS/Services/userrole/UserroleService.cs new file mode 100644 index 0000000..52d4f94 --- /dev/null +++ b/backend/ModernWMS.WMS/Services/userrole/UserroleService.cs @@ -0,0 +1,225 @@ +/* + * date:2022-12-20 + * developer:NoNo + */ +using Mapster; +using Microsoft.EntityFrameworkCore; +using ModernWMS.Core.DBContext; +using ModernWMS.Core.Services; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using Microsoft.Extensions.Localization; +using Microsoft.EntityFrameworkCore.Infrastructure.Internal; +using ModernWMS.Core.JWT; +using System.Text; +using System.Collections.Immutable; +using ModernWMS.Core.Models; + +namespace ModernWMS.WMS.Services +{ + /// + /// Userrole Service + /// + public class UserroleService : BaseService, IUserroleService + { + #region Args + /// + /// The DBContext + /// + private readonly SqlDBContext _dBContext; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + #endregion + + #region constructor + /// + ///Userrole constructor + /// + /// The DBContext + /// Localizer + public UserroleService( + SqlDBContext dBContext + , IStringLocalizer stringLocalizer + ) + { + this._dBContext = dBContext; + this._stringLocalizer = stringLocalizer; + } + #endregion + + #region Api + /// + /// bulk save records + /// + /// viewmodel + /// current user + /// + public async Task<(bool flag, string msg)> BulkSaveAsync(List viewModels, CurrentUser currentUser) + { + StringBuilder sb = new StringBuilder(); + var DBSet = _dBContext.GetDbSet(); + var repaet_role_name_viewmodel = viewModels.Where(t => t.id >= 0).GroupBy(t => t.role_name).Select(t => new { role_name = t.Key, cnt = t.Count() }).Where(t => t.cnt > 1).ToList(); + foreach (var repeat in repaet_role_name_viewmodel) + { + sb.AppendLine(string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["role_name"], repeat)); + } + if (repaet_role_name_viewmodel.Count() > 0) + { + return (false, sb.ToString()); + } + var delete_viewmodels = viewModels.Where(t => t.id < 0).ToList(); + var enties_check = await DBSet.AsNoTracking().Where(t => t.tenant_id == currentUser.tenant_id && !delete_viewmodels.Select(e => -e.id).ToList().Contains(t.id)).ToListAsync(); + var role_name_viewmodels = viewModels.Where(t => t.id >= 0).Select(t => t.role_name).ToList(); + var repaet_role_name_exists = enties_check.Where(t => role_name_viewmodels.Contains(t.role_name)).ToList(); + foreach (var repeat in repaet_role_name_exists) + { + sb.AppendLine(string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["role_name"], repeat.role_name)); + } + if (repaet_role_name_exists.Count() > 0) + { + return (false, sb.ToString()); + } + var add_entities = (from vm in viewModels + where vm.id == 0 + select new UserroleEntity + { + id = 0, + create_time = DateTime.Now, + last_update_time = DateTime.Now, + is_valid = true, + role_name = vm.role_name, + tenant_id = currentUser.tenant_id, + }).ToList(); + await DBSet.AddRangeAsync(add_entities); + var update_viewmodel_id = viewModels.Where(t => t.id > 0).Select(t => t.id).ToList(); + var update_entities = await DBSet.Where(t => update_viewmodel_id.Contains(t.id)).ToListAsync(); + update_entities.ForEach(t => + { + var update_vm = viewModels.FirstOrDefault(e => e.id == t.id); + if (update_vm != null) + { + t.last_update_time = DateTime.Now; + t.is_valid = update_vm.is_valid; + t.role_name = update_vm.role_name; + } + }); + + var delete_entites = await DBSet.Where(t => delete_viewmodels.Select(e => -e.id).ToList().Contains(t.id)).ToListAsync(); + DBSet.RemoveRange(delete_entites); + await _dBContext.SaveChangesAsync(); + return (true, _stringLocalizer["save_success"]); + } + /// + /// Get all records + /// + /// + public async Task> GetAllAsync(CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var data = await DbSet.AsNoTracking().Where(t => t.tenant_id == currentUser.tenant_id).ToListAsync(); + return data.Adapt>(); + } + + /// + /// Get a record by id + /// + /// + public async Task GetAsync(int id) + { + var DbSet = _dBContext.GetDbSet(); + var entity = await DbSet.AsNoTracking().FirstOrDefaultAsync(t => t.id.Equals(id)); + if (entity == null) + { + return null; + } + return entity.Adapt(); + } + /// + /// add a new record + /// + /// viewmodel + /// current user + /// + public async Task<(int id, string msg)> AddAsync(UserroleViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.role_name == viewModel.role_name && t.tenant_id == currentUser.tenant_id)) + { + return (0, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["role_name"], viewModel.role_name)); + } + var entity = viewModel.Adapt(); + entity.id = 0; + entity.create_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + await DbSet.AddAsync(entity); + await _dBContext.SaveChangesAsync(); + if (entity.id > 0) + { + return (entity.id, _stringLocalizer["save_success"]); + } + else + { + return (0, _stringLocalizer["save_failed"]); + } + } + /// + /// update a record + /// + /// args + /// currentUser + /// + public async Task<(bool flag, string msg)> UpdateAsync(UserroleViewModel viewModel, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + if (await DbSet.AnyAsync(t => t.id != viewModel.id && t.role_name == viewModel.role_name && t.tenant_id == currentUser.tenant_id)) + { + return (false, string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["role_name"], viewModel.role_name)); + } + var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) + { + return (false, _stringLocalizer["not exists entity"]); + } + var user_DBSet = _dBContext.GetDbSet(); + var this_role_users = await user_DBSet.Where(t=>t.user_role == entity.role_name).ToListAsync(); + this_role_users.ForEach(t=>t.user_role=viewModel.role_name); + entity.id = viewModel.id; + entity.role_name = viewModel.role_name; + entity.is_valid = viewModel.is_valid; + entity.last_update_time = DateTime.Now; + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// delete a record + /// + /// id + /// + public async Task<(bool flag, string msg)> DeleteAsync(int id) + { + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["delete_success"]); + } + else + { + return (false, _stringLocalizer["delete_failed"]); + } + } + #endregion + } +} + diff --git a/backend/ModernWMS.sln b/backend/ModernWMS.sln new file mode 100644 index 0000000..1601cb4 --- /dev/null +++ b/backend/ModernWMS.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33122.133 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModernWMS", "ModernWMS\ModernWMS.csproj", "{59E73801-09AE-4234-9B14-9FF5787F7004}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModernWMS.Core", "ModernWMS.Core\ModernWMS.Core.csproj", "{8E8FC264-84FF-4353-B68B-ED007859E095}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModernWMS.WMS", "ModernWMS.WMS\ModernWMS.WMS.csproj", "{2A69B0EE-95A8-4459-96DE-867C160EA615}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {59E73801-09AE-4234-9B14-9FF5787F7004}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {59E73801-09AE-4234-9B14-9FF5787F7004}.Debug|Any CPU.Build.0 = Debug|Any CPU + {59E73801-09AE-4234-9B14-9FF5787F7004}.Release|Any CPU.ActiveCfg = Release|Any CPU + {59E73801-09AE-4234-9B14-9FF5787F7004}.Release|Any CPU.Build.0 = Release|Any CPU + {8E8FC264-84FF-4353-B68B-ED007859E095}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8E8FC264-84FF-4353-B68B-ED007859E095}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8E8FC264-84FF-4353-B68B-ED007859E095}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8E8FC264-84FF-4353-B68B-ED007859E095}.Release|Any CPU.Build.0 = Release|Any CPU + {2A69B0EE-95A8-4459-96DE-867C160EA615}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A69B0EE-95A8-4459-96DE-867C160EA615}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A69B0EE-95A8-4459-96DE-867C160EA615}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A69B0EE-95A8-4459-96DE-867C160EA615}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0CEBCBBC-DCCB-4D5C-A47F-9046F3BF0AB9} + EndGlobalSection +EndGlobal diff --git a/backend/ModernWMS/ModernWMS.csproj b/backend/ModernWMS/ModernWMS.csproj new file mode 100644 index 0000000..b2329f1 --- /dev/null +++ b/backend/ModernWMS/ModernWMS.csproj @@ -0,0 +1,28 @@ + + + + net7.0 + enable + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + diff --git a/backend/ModernWMS/Program.cs b/backend/ModernWMS/Program.cs new file mode 100644 index 0000000..c5bcf28 --- /dev/null +++ b/backend/ModernWMS/Program.cs @@ -0,0 +1,45 @@ + +using Microsoft.AspNetCore.Hosting; +using NLog.Web; + +namespace ModernWMS +{ + public class Program + { + public static void Main(string[] args) + { + var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger(); + try + { + logger.Debug("--- run"); + CreateHostBuilder(args).Build().Run(); + } + catch (Exception exception) + { + logger.Error(exception, "---- exception"); + throw; + } + finally + { + NLog.LogManager.Shutdown(); + } + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseUrls("http://*:5555") + .UseStartup() + .UseKestrel(opt => opt.Limits.MaxRequestBodySize = null); + }).ConfigureLogging(logging => + { + logging.ClearProviders(); + logging.SetMinimumLevel(LogLevel.Trace); + }).UseNLog() + .UseDefaultServiceProvider(options => + { + options.ValidateScopes = false; + }); + } +} diff --git a/backend/ModernWMS/Properties/launchSettings.json b/backend/ModernWMS/Properties/launchSettings.json new file mode 100644 index 0000000..12fae4f --- /dev/null +++ b/backend/ModernWMS/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:16453", + "sslPort": 0 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5056", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/backend/ModernWMS/Startup.cs b/backend/ModernWMS/Startup.cs new file mode 100644 index 0000000..749f257 --- /dev/null +++ b/backend/ModernWMS/Startup.cs @@ -0,0 +1,42 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System; +using ModernWMS.Core.Extentions; +namespace ModernWMS +{ + public class Startup + { + /// + /// startup + /// + /// Config + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + /// + /// register service + /// + /// services + public void ConfigureServices(IServiceCollection services) + { + services.AddExtensionsService(Configuration); + } + + /// + /// configure + /// + /// app + /// env + /// serviceProvider + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider service_provider) + { + app.UseExtensionsConfigure(env, service_provider, Configuration); + } + } +} diff --git a/backend/ModernWMS/appsettings.Development.json b/backend/ModernWMS/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/backend/ModernWMS/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/backend/ModernWMS/appsettings.json b/backend/ModernWMS/appsettings.json new file mode 100644 index 0000000..e0b16c6 --- /dev/null +++ b/backend/ModernWMS/appsettings.json @@ -0,0 +1,31 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Database": { "db": "MySql" }, + "ConnectionStrings": { + "MySqlConn": "Server=127.0.0.1;Database=wms;Port=3306;charset=utf8;uid=root;pwd=123456789a?;", + "SqlLiteConn": "Data Source = wms.db" + }, + "SwaggerSettings": { + "Name": "ModernWMS", + "ApiTitle": "ModernWMS_API", + "ApiVersion": "V1.0", + "ApiDescription": "ModernWMS_API", + "SecurityDefinition": false, + "XmlFiles": [ + "ModernWMS.Core.xml", + "ModernWMS.WMS.xml" + ] + }, + "TokenSettings": { + "Audience": "ModernWMS", + "Issuer": "ModernWMS", + "SigningKey": "ModernWMS_SigningKey", + "ExpireMinute": 60 + } +} diff --git a/backend/ModernWMS/nlog.config b/backend/ModernWMS/nlog.config new file mode 100644 index 0000000..36541e0 --- /dev/null +++ b/backend/ModernWMS/nlog.config @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/ModernWMS/wms.db b/backend/ModernWMS/wms.db new file mode 100644 index 0000000000000000000000000000000000000000..e81be572293f0c11dbfd288e7646cfb3a7873724 GIT binary patch literal 151552 zcmeI5Pi)*)e#c2k)@USAV_Q+^*ilT4?bw21OC#BlwS_TJl(AQ^G;-we#zqzgv8=Qx;Q#R=d+4!fF9mvC^w2JHXn^+8?Qwzat*7m!w*?xsC<3&HK9ck1KObkT zS;w-!gOP@Ozu)`u&FA;t<9p;A{;q$zVz|0=$Fd8GE6s5Sxt<>GBT3>ou7~`cB7gMt z9@*%lJLHqE*$&(6;m*lN4-jc@;(JeLJn_GY|4Dp5u+;ynzF#MP2+M|a5C8!XXqUjF z{6I_`ALpMBPD5aQaU3HO5~L^w4}70&1J4+ z)}`!PPRia`S&^33ve$F#izHo2Ub`w+b6s0sUR_+jC0)(jk``~|)|Rux{%R(h`=D%& zs>-HP(34UwbCZ}Xo2}>=?rw-k(KK6koDivAP>g(tte}|6rf!EwRm*f0)sTzv}lJ-;*nWH;D5$Eqhljf5sa8 zQBLmAA(dRw9x1D`TvAkQJ*0Zk8n{oI!b9gk&=fBD@D;~&EZZ%A^w*;=r*=lZk|`2A z(QMgZDN(Orx+dTC`n|@^mg?*i>eu@E#i=R&me1U|nkNvSQrnO4X-!*i4Sg6iaN! zZ?omzF_^W2oU}?xo~_eP?Q*ufwy~+REfp*~LPJvukydteV{^+5p?c5CmqJgXPN`VT z8@kPAN|hKxj7`hZ9NF42BW%^`G0g3gw)x;D9~0;2`G;$MOOoZx*KA8GsqW8o+aZN*FiXZg%RT+# z7xO%4n3{gS+?6OL*Yfw}mdBA(4asCkJtmTW!a?$HC@zryeB$3Y^2Q4UKmY_l00ck) z1V8`;KmY_l00cl_-w`;;_h!V|nc2CS)Xax7=jY~UQ}VKDxQ3En@^9qKpPM^_|?&}@rZ7Z)Abh9)%)Z05AFFCsHrNnxA$NZfEzITlG2m&Ag0w4eaAOHd&00JNY0w4eadn6zve&FIv>;1CZ0OQ|M^u{*~sgf;S?2D-O3w|Tf05Dw4PbaWu)BV$152rSu09PXM{nC zypo2Nl$Nu(%$3Z#lwHe7*&8b>($ZS?dTxD@q)W+bSLOPg*VdO;7uRn|S2MSy#T&V` zigCjiRA$ z>l$0fFkM@54417{RMhRr0{OTMbCYdKQQeY~XX`k|rpeZz1q!WdRH3Nbj%9{8f+{gQ zQTbA#N2+Kr4^`3fH^M5_jHrx$w&Etm^ePpKb!KqA=*~yXS}}qp~;=Si7;QNmg$nZF1vbI{=Ie*Z93C%!VgR_Iw4t-5CMY}rC{DXM9E8b+bsy6+__Qu1n`u)cD4Arzt+CyHmEv=-wKO++aQrHHwWSG0$(=UE8&vS;U>G#WBiBfVc ze_w8S968l8xtC1s2fXP$?*B($W$Hw?4$Nh^xUWh~Q?_m9<9WSYRC8yPW zsK#qJL5`YBHm%nicxtTs4h3?3Cm(hv^j=Aq$?A!%hU-4`;t&9WC8tLgBa_er( zA`wlQm&dDGjM`9DA~qFPyKT@c+7?+^!CI$7zYxo4MJKPDo1x9VqP1ga(MnrnwMDcR z^Y%mKfO$)4ytGaGBAbZF!VsDCt{b7t4V*1Ke}}D-S9Zz038octzlN<4y>#hiG#*N( zp{BGtw~!0@j}Hw7y=bt2p}I(>x;0$i!m5JKnpbVU$hO5^%A@Jzwz*p(H^*3OSIA-@ zvbKYzQnU?~oau<;nfJ)5YRu|dFidjR+$Cq;uoX=ENCmKHYX z^~8)*G+ji*JlT6TG~H2cqv+k_4H@-rC^oYo^oBaiUzJ<)j3RH?iWzp^v}|M32rFPP z43JBv!5EzfePM)B(62@)?UQct;UA9#tILM`s!Idg)6YZom6#@X)_qiSMfM!3m00ck)1V8`;KmY_l00cl_{}J%!|D%Jqxx{w~H?cVKe(BS2SDOZ>?0d zAIJ~hPBz=W?Eiis!hUO|s{KHoxH%E$PA{AmmTUN|TKDt_>#bC(wms>{mr|UYTbL7W z)L14@J0nj^bfW2pD^`zE)e-*aIH4p=33KJzP_1!(MX2sp>P9tbIQ1T>N)zM4X+BP$ z;=7?ZdQcx~Q>N+8@X~mko1B>Rjz@mX;XR-Gy6(E4PJUT&YhY#B~0^i z|L3%8ca{`;)2fc3iCC5n@Uk}V~wOru$(xMI$9w>f9_B%MQzG7 z-HENgL%cgNCtM=XtOEIwGg;YQWm?T0BAjlK-me^qbC)JA30G=tE|nkcT2ubAW9U&^ zXjH8?2oEfY6~}qY`dgK_Ieof5sW0_*1()}`fK~Df@ah+?O_`=Uy_d&G1)Z1@F7R>B z*gDD9^o?2w{3F*W_k8?Tx%_btyY~p>CNs_H9*!DSfBrvomP`C&;?EM7$o&5wM!p(Z z5PlH8748WahW~r`?}qK+)X;wp{q2xR)bIiU5C8!X009sH0T2LzH-|uabbyQV@uj8s z`?E8%b7yB#XJA&COm+EzHd^MCrrSz$u0nLzF&54V+|XF+}Nu)W8Xb z7DJRyPy2lF5H;`~LyI9w4^ji;3@wHz z9j6A~WoR)(=>cls7(yqYN#EDBVvDyu;99h|&kBfg=nphA7=f4TuaahA7=j z4ZO|JVu;c`)W8@+iy=z$)WBN|Ertl||KFU`7rrS7fB*=900@8p2!H?xfB*=9z?(|| z^Zz&3_xR=@00JNY0w4eaAOHd&00JNY0&flh%>UmUU*nsC00@8p2!H?xfB*=900@8p z2)wxjgu!ht#+~E_&h+Pc|EuSO@Fzpxa3_b{S|X4BRE&vZWBjwv{Sb`aqY1pfWA&jI zy`;{9^DGPA(-}hKj($HxLgKfQV8>CB9%aY1 z$>TsmZ0H5W2rJo3iqXjq5&3BKt(X^>_~{ox@L2E3IwS(R_v{w`fhy(gBlXpxR@7Ow zsLvT$J-)OySaDrFvAbJjMA$8tpLj`eOHOzs-m;!WYI!bmGbd%&$lr~X6&k6R+Hs9S zSWS8*{Q3CyXiPkQoPQofRP}Ke$U}N68)6GjdI~S##vt2Xedt+eRo^fw*(UO(Ehh6PgjRj*)=K0O>0Pn_VN8r2SiJno2ux%R7Au=#e2 zN)||7pqkN)d#z~EokdhFYd7+D2NiLzb)qW~#2EUO-HkyT1vQ=I7>qg7a*uvl> z$MF-QDDqF%s#VB8@Mw!_^8yv7onZ9arIw|mL^^1dOdqp*f&L@?{_whST>U8jwjb*J z*;D|i9Fd+rX6j5X>l_>YJTI|-_h z~Zyzo-w~meSWpt9$f!vlzyuSHs5J*y4O$xNr!%~%^2zWHpbLZqvao= z+ug9NZJF6FRjXvWy2e)0j5~L9TQ^C6#x`c_iW@o`@GBwd5yK|~dp|GJZtF!y2&7ZS z{r}o49oPl|5C8!X009sH0T2KI5C8!X0D;$&0OtR%r(f}{KmY_l00ck)1V8`;KmY_l z00cmwmH_7ewKT8|0w4eaAOHd&00JNY0w4eaAOHfdCjrd=Ur)c{TY&%wfB*=900@8p z2!H?xfB*=9KrI2x|7&Sr8w5ZA1V8`;KmY_l00ck)1V8`;UQYtv{GU%0Ir7E}1V8`; zKmY_l00ck)1V8`;KmY_lpi2ZE2>b{qih?*6U!4}0mg0(5FwE+|f|A$O^Qv-wcJ87w zv#~%vW@j{2y)d(&e0XR6!o~9o8}kb@7Z(<0&d;3x=_nKg&PJ zP@C~uT(Uxe5mB)lcVD?F_q$< z2k~|N=%D3b^P27|M!q>E*&=LcU6vP!9@>yUGKi>OD!H7C8Fu$ah!x6=?Ag7@oFqo9 z^N(n36O*}PXN4J|q8HJwi~E16tIT3WomwD?Je1Q2~(JQfqrp5>p9 z`cZ6Y<)sayabK#hn2qAjs%3NT$Vy4G(8eVZo|!9|bt$`+ld?BfR%lFBb_nN2y}YF= zu3?#bs^%UucF0*zBPx7tyY(sAUM+8^c9b9WZ+*8$r4_pMb*@odU*&40%qsV2;b=@e zeVTuo@~hmAV(VL0$B3;L^#pzxJLvs|Gf(7D#^ zQ0jMfp!0_pj`(ryA7Ap@D`}~=ZRK_P`EI?(X>w-{ujYzuo8GZmu8wXAU2Ak~Ze(Td z4RLIYfA)EWoA))3HS_A6RU7TXJCHrQ~jrF_3MToAovxoR(tZtrY*@Q##hK9qI(*>88O`v&yNm6Kdud zH6x}FGv&!glOl0ni}Bdwjdx?>=qUeu%6C5*B$M|Kj4&vXmp4Xh8qP?y=kIG| z*yzoCBAZBgV$@`fws&GhRxK^maYSr}*Nh$A*xYjK-BKBM<#jV$xMOJUR!GJzmeqS! zz7$$hOQsQ48r5>bL`BQ3KpP)n_00JNY0w4eaAOHd&00JNY0wB)iWp; b2!H?xfB*=900@8p2!H?xfB*<|kHG%}Hi9qM literal 0 HcmV?d00001 diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 0000000..e69de29 diff --git a/backend/readme.txt b/backend/readme.txt new file mode 100644 index 0000000..e69de29 diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..160bba0 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,18 @@ +FROM ubuntu:22.04 + +RUN apt-get update && apt-get install -y wget curl +RUN wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \ + && dpkg -i packages-microsoft-prod.deb \ + && apt-get update \ + && apt-get install -y aspnetcore-runtime-7.0 nginx \ + && curl -fsSL https://deb.nodesource.com/setup_16.x | /bin/bash - \ + && apt install -y nodejs \ + && mkdir -p /app/ /frontend/ +WORKDIR /app +COPY ./nginx.conf /etc/nginx/nginx.conf +COPY ./frontend /frontend/ +COPY ./backend /app/ +COPY ./run.sh /app/run.sh +RUN chmod u+x /app/run.sh +EXPOSE 80 +ENTRYPOINT ["/bin/bash"] \ No newline at end of file diff --git a/docker/backend/web.config b/docker/backend/web.config new file mode 100644 index 0000000..e69de29 diff --git a/docker/frontend/index.html b/docker/frontend/index.html new file mode 100644 index 0000000..e69de29 diff --git a/docker/nginx.conf b/docker/nginx.conf new file mode 100644 index 0000000..7dfb056 --- /dev/null +++ b/docker/nginx.conf @@ -0,0 +1,60 @@ +#user nobody; +worker_processes 1; + +events { + worker_connections 1024; +} + + +http { + include mime.types; + default_type application/octet-stream; + + log_format main '[$remote_addr] [conn:$connection] [conn_req:$connection_requests] ' + '[$time_iso8601] "$request" [$http_referer] [$http_user_agent] ' + '[body:$body_bytes_sent] [request_length:$request_length] [status:$status] [request_time:$request_time] [$http_UserName]'; + + #access_log logs/access.log main; + + sendfile on; + #tcp_nopush on; + + #keepalive_timeout 0; + keepalive_timeout 65; + #gzip on; + + #wms ModernWMS backend + #server { + #listen 21011; + #server_name server localhost; # xxx.xxx.xxx.xxx your ip address + #location / { + # proxy_pass http://127.0.0.1:20011; + # root html; + # index index.html index.htm; + # proxy_set_header X-Real-IP $remote_addr; + #} + #proxy_send_timeout 300; + #proxy_read_timeout 300; + # + #client_max_body_size 1024m; + # client_header_buffer_size 10m; + # large_client_header_buffers 4 10m; + # proxy_buffers 16 1024k; + # proxy_buffer_size 1024k; + #} + #wms ModernWMS frontend + server { + listen 80; + server_name localhost; + location / { + root /frontend/; + index index.html index.htm; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root html; + } + } + +} diff --git a/docker/run.sh b/docker/run.sh new file mode 100644 index 0000000..85d4a04 --- /dev/null +++ b/docker/run.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# start 1 +/usr/sbin/nginx -g 'daemon off;' > /var/log/start1.log 2>&1 & +# start 2 +dotnet /app/ModernWMS.dll --urls http://0.0.0.0:21011 > /var/log/start2.log 2>&1 & +# just keep this script running +while [[ true ]]; do + sleep 1 +done \ No newline at end of file diff --git a/frontend/.env.development b/frontend/.env.development new file mode 100644 index 0000000..7c552fc --- /dev/null +++ b/frontend/.env.development @@ -0,0 +1,6 @@ +ENV = 'development' + +VITE_CLI_PORT = 5173 +VITE_SERVER_PORT = 21011 +VITE_BASE_API = /api +VITE_BASE_PATH = http://192.168.103.80 diff --git a/frontend/.env.production b/frontend/.env.production new file mode 100644 index 0000000..39576f1 --- /dev/null +++ b/frontend/.env.production @@ -0,0 +1,6 @@ +ENV = 'production' + +VITE_CLI_PORT = 5174 +VITE_SERVER_PORT = 20011 +VITE_BASE_API = /api +VITE_BASE_PATH = https://wmsonline.ikeyly.com diff --git a/frontend/.eslintrc b/frontend/.eslintrc new file mode 100644 index 0000000..973a451 --- /dev/null +++ b/frontend/.eslintrc @@ -0,0 +1,82 @@ +{ + "root": true, + "globals": { + "defineEmits": "readonly", + "defineProps": "readonly", + "defineExpose": "readonly" + }, + "extends": ["plugin:@typescript-eslint/recommended", "plugin:vue/vue3-recommended", "airbnb-base"], + "parserOptions": { + "parser": "@typescript-eslint/parser", + "ecmaVersion": 2020 + }, + "rules": { + "camelcase": "off", + "no-bitwise": "off", // 禁用按位运算符 + "no-tabs": "off", // 禁用 tab + "array-element-newline": ["error", "consistent"], // 强制数组元素间出现换行 + "indent": "off", // 强制使用一致的缩进 + "quotes": ["error", "single"], // 强制使用一致的反勾号、双引号或单引号 + "comma-dangle": "off", // 要求或禁止末尾逗号 + "object-curly-spacing": ["error", "always"], // 强制在大括号中使用一致的空格 + "max-len": ["error", 200], // 强制一行的最大长度; 注意: 这里特意调整的比prettierrc多50, 因为某些情况下两个插件格式化出来的结果不同导致界面上有波浪线 + "no-new": "off", // 禁止使用 new 以避免产生副作用 + "linebreak-style": "off", // 强制使用一致的换行风格 + "import/extensions": "off", // 确保在导入路径中统一使用文件扩展名 + "eol-last": "off", // 要求或禁止文件末尾存在空行 + "no-shadow": "off", // 禁止变量声明与外层作用域的变量同名 + "no-unused-vars": "warn", // 禁止出现未使用过的变量 + "import/no-cycle": "off", // 禁止一个模块导入一个有依赖路径的模块回到自己身上 + "arrow-parens": "off", // 要求箭头函数的参数使用圆括号 + "semi": ["error", "never"], // 要求或禁止使用分号代替 ASI + "eqeqeq": "off", // 要求使用 === 和 !== + "no-param-reassign": "off", // 禁止对 function 的参数进行重新赋值 + "import/prefer-default-export": "off", // 如果模块只输入一个名字,则倾向于默认输出 + "no-use-before-define": "off", // 禁止在变量定义之前使用它们,则倾向于默认输出 + "no-continue": "off", // 禁用 continue 语句 + "prefer-destructuring": "off", // 优先使用数组和对象解构 + "no-plusplus": "off", // 禁用一元操作符 ++ 和 -- + "prefer-const": "warn", // 要求使用 const 声明那些声明后不再被修改的变量 + "global-require": "off", // 要求 require() 出现在顶层模块作用域中 + "no-prototype-builtins": "off", // 禁止直接调用 Object.prototypes 的内置属性 + "consistent-return": "off", // 要求 return 语句要么总是指定返回的值,要么不指定 + "one-var-declaration-per-line": "off", // 要求或禁止在变量声明周围换行 + "one-var": "off", // 强制函数中的变量要么一起声明要么分开声明 + "import/named": "off", // 确保命名导入与远程文件中的命名导出相对应 + "object-curly-newline": "off", // 强制大括号内换行符的一致性 + "default-case": "off", // 要求 switch 语句中有 default 分支 + "no-trailing-spaces": "off", // 禁用行尾空格 + "func-names": "off", // 要求或禁止使用命名的 function 表达式 + "radix": "off", // 强制在 parseInt() 使用基数参数 + "no-unused-expressions": "off", // 禁止出现未使用过的表达式 + "no-underscore-dangle": "off", // 禁止标识符中有悬空下划线 + "no-nested-ternary": "off", // 禁用嵌套的三元表达式 + "no-restricted-syntax": "off", // 禁用特定的语法 + "no-await-in-loop": "off", // 禁止在循环中出现 await + "import/no-extraneous-dependencies": "off", // 禁止使用外部包 + "import/no-unresolved": "off", // 确保导入指向一个可以解析的文件/模块 + "template-curly-spacing": ["error", "always"], // 要求或禁止模板字符串中的嵌入表达式周围空格的使用 + "@typescript-eslint/no-var-requires": "off", // 除import语句外,禁止使用require语句 + "@typescript-eslint/no-empty-function": "off", // 不允许空函数 + "@typescript-eslint/no-explicit-any": "off", // 禁止使用 any 类型 + "guard-for-in": "off", // 要求 for-in 循环中有一个 if 语句 + "class-methods-use-this": "off", // 强制类方法使用 this + "vue/html-indent": ["error", 2], // 在