From 0ae3c5aa071ca0daa01d70f5cb6ee7ada3892e91 Mon Sep 17 00:00:00 2001 From: pro Date: Tue, 20 Jan 2026 20:43:38 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=B3=84=EC=A2=8C=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 18 + .dockerignore:Zone.Identifier | Bin 0 -> 25 bytes .editorconfig:Zone.Identifier | Bin 0 -> 25 bytes .env:Zone.Identifier | Bin 0 -> 25 bytes .gitattributes:Zone.Identifier | Bin 0 -> 25 bytes .gitignore:Zone.Identifier | Bin 0 -> 25 bytes CLAUDE.md:Zone.Identifier | Bin 0 -> 25 bytes CURRENT_WORKS.md:Zone.Identifier | Bin 0 -> 25 bytes LOGICAL_RELATIONSHIPS.md:Zone.Identifier | Bin 0 -> 25 bytes README.md:Zone.Identifier | Bin 0 -> 25 bytes REMOTE_WORK_SETUP.md:Zone.Identifier | Bin 0 -> 25 bytes .../CleanupExpiredLinks.php:Zone.Identifier | Bin 0 -> 25 bytes .../CleanupTempFiles.php:Zone.Identifier | Bin 0 -> 25 bytes .../Commands/CleanupTrash.php:Zone.Identifier | Bin 0 -> 25 bytes ...FcmPruneInvalidCommand.php:Zone.Identifier | Bin 0 -> 25 bytes .../FcmSendCommand.php:Zone.Identifier | Bin 0 -> 25 bytes .../FcmTestCommand.php:Zone.Identifier | Bin 0 -> 25 bytes ...ateSimpleRelationships.php:Zone.Identifier | Bin 0 -> 25 bytes ...ModelWithRelationships.php:Zone.Identifier | Bin 0 -> 25 bytes .../Migrate5130Items.php:Zone.Identifier | Bin 0 -> 25 bytes .../PruneAuditLogs.php:Zone.Identifier | Bin 0 -> 25 bytes .../RecordStorageUsage.php:Zone.Identifier | Bin 0 -> 25 bytes .../SeedMenuPermissions.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantsBootstrap.php:Zone.Identifier | Bin 0 -> 25 bytes ...teLogicalRelationships.php:Zone.Identifier | Bin 0 -> 25 bytes app/Console/Kernel.php:Zone.Identifier | Bin 0 -> 25 bytes .../SystemFields.php:Zone.Identifier | Bin 0 -> 25 bytes app/Enums/EstimateStatus.php:Zone.Identifier | Bin 0 -> 25 bytes app/Enums/OrderStatus.php:Zone.Identifier | Bin 0 -> 25 bytes ...DuplicateCodeException.php:Zone.Identifier | Bin 0 -> 25 bytes app/Exceptions/Handler.php:Zone.Identifier | Bin 0 -> 25 bytes .../DailyReportExport.php:Zone.Identifier | Bin 0 -> 25 bytes .../ExpenseEstimateExport.php:Zone.Identifier | Bin 0 -> 25 bytes app/Helpers/ApiResponse.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemTypeHelper.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantCodeGenerator.php:Zone.Identifier | Bin 0 -> 25 bytes .../GlobalMenuController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/AccountController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Admin/FcmController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/AdminController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/AiReportController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/ApiController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/ApprovalController.php:Zone.Identifier | Bin 0 -> 25 bytes ...ApprovalFormController.php:Zone.Identifier | Bin 0 -> 25 bytes ...ApprovalLineController.php:Zone.Identifier | Bin 0 -> 25 bytes .../AttendanceController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/BadDebtController.php:Zone.Identifier | Bin 0 -> 25 bytes .../BankAccountController.php:Zone.Identifier | Bin 0 -> 25 bytes ...kTransactionController.php:Zone.Identifier | Bin 0 -> 25 bytes ...obillSettingController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/BillController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/BoardController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/CardController.php:Zone.Identifier | Bin 0 -> 25 bytes ...dTransactionController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/CategoryController.php:Zone.Identifier | Bin 0 -> 25 bytes ...ategoryFieldController.php:Zone.Identifier | Bin 0 -> 25 bytes .../CategoryLogController.php:Zone.Identifier | Bin 0 -> 25 bytes ...goryTemplateController.php:Zone.Identifier | Bin 0 -> 25 bytes ...assificationController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/ClientController.php:Zone.Identifier | Bin 0 -> 25 bytes .../ClientGroupController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/CommonController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/CompanyController.php:Zone.Identifier | Bin 0 -> 25 bytes ...siveAnalysisController.php:Zone.Identifier | Bin 0 -> 25 bytes .../ContractController.php:Zone.Identifier | Bin 0 -> 25 bytes .../DailyReportController.php:Zone.Identifier | Bin 0 -> 25 bytes .../DashboardController.php:Zone.Identifier | Bin 0 -> 25 bytes .../DepartmentController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/DepositController.php:Zone.Identifier | Bin 0 -> 25 bytes .../AuditLogController.php:Zone.Identifier | Bin 0 -> 25 bytes ...mCalculationController.php:Zone.Identifier | Bin 0 -> 25 bytes .../BomTemplateController.php:Zone.Identifier | Bin 0 -> 25 bytes .../DesignModelController.php:Zone.Identifier | Bin 0 -> 25 bytes ...ModelVersionController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/EmployeeController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/EstimateController.php:Zone.Identifier | Bin 0 -> 25 bytes ...ectedExpenseController.php:Zone.Identifier | Bin 0 -> 25 bytes .../FileStorageController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/FolderController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/InternalController.php:Zone.Identifier | Bin 0 -> 25 bytes .../CustomTabController.php:Zone.Identifier | Bin 0 -> 25 bytes ...RelationshipController.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemBomItemController.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemFieldController.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemMasterController.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemPageController.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemSectionController.php:Zone.Identifier | Bin 0 -> 25 bytes ...tionTemplateController.php:Zone.Identifier | Bin 0 -> 25 bytes .../UnitOptionController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/ItemsBomController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/ItemsController.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemsFileController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/LeaveController.php:Zone.Identifier | Bin 0 -> 25 bytes .../LeavePolicyController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/LoanController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Controllers/Api/V1/MaterialController.php | 52 + .../V1/MaterialController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/MenuController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/ModelSetController.php:Zone.Identifier | Bin 0 -> 25 bytes ...ationSettingController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/OrderController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/PaymentController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/PayrollController.php:Zone.Identifier | Bin 0 -> 25 bytes .../PermissionController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/PlanController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/PopupController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/PositionController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/PostController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/PricingController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/ProductBomItemController.php | 114 ++ ...oductBomItemController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Controllers/Api/V1/ProductController.php | 82 ++ .../V1/ProductController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/PurchaseController.php:Zone.Identifier | Bin 0 -> 25 bytes ...NotificationController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/QuoteController.php:Zone.Identifier | Bin 0 -> 25 bytes .../ReceivablesController.php:Zone.Identifier | Bin 0 -> 25 bytes .../ReceivingController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/RefreshController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/RegisterController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/ReportController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/RoleController.php:Zone.Identifier | Bin 0 -> 25 bytes ...lePermissionController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/SalaryController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/SaleController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/ShipmentController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/SiteController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/StockController.php:Zone.Identifier | Bin 0 -> 25 bytes ...SubscriptionController.php:Zone.Identifier | Bin 0 -> 25 bytes .../SystemBoardController.php:Zone.Identifier | Bin 0 -> 25 bytes .../SystemPostController.php:Zone.Identifier | Bin 0 -> 25 bytes .../TaxInvoiceController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/TenantController.php:Zone.Identifier | Bin 0 -> 25 bytes ...FieldSettingController.php:Zone.Identifier | Bin 0 -> 25 bytes ...tOptionGroupController.php:Zone.Identifier | Bin 0 -> 25 bytes ...tOptionValueController.php:Zone.Identifier | Bin 0 -> 25 bytes ...antStatFieldController.php:Zone.Identifier | Bin 0 -> 25 bytes ...tUserProfileController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/UserController.php:Zone.Identifier | Bin 0 -> 25 bytes ...erInvitationController.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/UserRoleController.php:Zone.Identifier | Bin 0 -> 25 bytes ...VendorLedgerController.php:Zone.Identifier | Bin 0 -> 25 bytes .../WithdrawalController.php:Zone.Identifier | Bin 0 -> 25 bytes .../WorkOrderController.php:Zone.Identifier | Bin 0 -> 25 bytes .../WorkResultController.php:Zone.Identifier | Bin 0 -> 25 bytes .../WorkSettingController.php:Zone.Identifier | Bin 0 -> 25 bytes .../Controller.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/ProcessController.php:Zone.Identifier | Bin 0 -> 25 bytes app/Http/Kernel.php:Zone.Identifier | Bin 0 -> 25 bytes .../ApiKeyMiddleware.php:Zone.Identifier | Bin 0 -> 25 bytes .../ApiRateLimiter.php:Zone.Identifier | Bin 0 -> 25 bytes .../CheckPermission.php:Zone.Identifier | Bin 0 -> 25 bytes .../CheckSwaggerAuth.php:Zone.Identifier | Bin 0 -> 25 bytes .../CorsMiddleware.php:Zone.Identifier | Bin 0 -> 25 bytes .../LogApiRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Middleware/PermMapper.php:Zone.Identifier | Bin 0 -> 25 bytes ...pdateAgreementsRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../WithdrawRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../FcmHistoryRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../FcmTokenListRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Admin/SendFcmRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/FileMoveRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/FileUploadRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/FolderStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../FolderUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Api/V1/RefreshRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../V1/ShareLinkRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../FormIndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../FormStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../FormUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../InboxIndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Approval/IndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../LineIndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../LineStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../LineUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ReferenceIndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../RejectRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Approval/StoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../SubmitRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../CheckInRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../CheckOutRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../IndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../MonthlyStatsRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../StoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../AuditLogIndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...BarobillSettingRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../BoardStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../BoardUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../CommentStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PostStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PostUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../CategoryMoveRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...CategoryReorderRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../CategoryStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../CategoryUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...egoryFieldStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...goryFieldUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ClientStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ClientUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PaginateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ContractStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ContractUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../CloneRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../DiffRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ReplaceItemsRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpsertRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../CalculateBomRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...imateParametersRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Model/StoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Model/UpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../CreateDraftRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...eCompanyFormulaRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Employee/IndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Employee/StoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../CreateEstimateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateEstimateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ExchangeTokenRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...ItemBatchDeleteRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemFileUploadRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Item/ItemStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../CustomTabStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...CustomTabUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...entBomItemStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...ndentFieldStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...entSectionStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...temBomItemStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...emBomItemUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemFieldStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...ItemFieldUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemPageStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemPageUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...temSectionStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...emSectionUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../LinkEntityRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...erRelationshipsRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ReorderRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...onTemplateStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...nTemplateUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...UnitOptionStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...ItemsFileUploadRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Leave/BalanceRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Leave/IndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Leave/RejectRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Leave/StoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Leave/UpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...lculateInterestRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Loan/LoanIndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../LoanSettleRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Loan/LoanStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../LoanUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Material/MaterialStoreRequest.php | 32 + .../MaterialStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Material/MaterialUpdateRequest.php | 32 + .../MaterialUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...lkUpdateSettingRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...eGroupedSettingRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateSettingRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...CreateFromQuoteRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...ProductionOrderRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../StoreOrderRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateOrderRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...dateOrderStatusRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...PositionReorderRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PositionRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PriceByItemsRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PriceCostRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PriceIndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PriceStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PriceUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Requests/Product/ProductStoreRequest.php | 42 + .../ProductStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Requests/Product/ProductUpdateRequest.php | 42 + .../ProductUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../RegisterTokenRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateSettingsRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...omBulkCalculateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...oteBomCalculateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...QuoteBulkDeleteRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteCalculateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteIndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteSendEmailRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteSendKakaoRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../RegisterRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ShipmentStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ShipmentUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...entUpdateStatusRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...ancelTaxInvoiceRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...reateTaxInvoiceRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../TaxInvoiceListRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...xInvoiceSummaryRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...pdateTaxInvoiceRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...enantLogoUploadRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...tStatFieldStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...StatFieldUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PasswordChangeRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../SwitchTenantRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UserUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...cceptInvitationRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../InviteUserRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ListInvitationRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...iReportGenerateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../AiReportListRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...BadDebtDocumentRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...toreBadDebtMemoRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../StoreBadDebtRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateBadDebtRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...toreBankAccountRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...dateBankAccountRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Bill/StoreBillRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateBillRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...pdateBillStatusRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Card/StoreCardRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateCardRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...kBusinessNumberRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...nyRequestActionRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...anyRequestIndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...anyRequestStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...hboardApprovalsRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...DashboardChartsRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../StoreDepositRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateDepositRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...ExpectedExpenseRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...ExpectedExpenseRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...ctedPaymentDateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PaymentActionRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PaymentIndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PaymentStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...alculatePayrollRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PayPayrollRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../StorePayrollRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdatePayrollRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...ePayrollSettingRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Plan/PlanIndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Plan/PlanStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../PlanUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../StorePopupRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdatePopupRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../StoreProcessRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateProcessRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../StorePurchaseRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdatePurchaseRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...rocessReceivingRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../StoreReceivingRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...UpdateReceivingRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../DailyReportRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...ExpenseEstimateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...ulkUpdateStatusRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../StoreSalaryRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateSalaryRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../SendStatementRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Sale/StoreSaleRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateSaleRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Site/StoreSiteRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../UpdateSiteRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../ExportStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...scriptionCancelRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...bscriptionIndexRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...bscriptionStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...StoreWithdrawalRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...pdateWithdrawalRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...tendanceSettingRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...dateWorkSettingRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...WorkOrderAssignRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../WorkOrderIssueRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...WorkOrderStatusRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../WorkOrderStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...WorkOrderUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...WorkResultStoreRequest.php:Zone.Identifier | Bin 0 -> 25 bytes ...orkResultUpdateRequest.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/ApiKey.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/ApiRequestLog.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Audit/AuditLog.php:Zone.Identifier | Bin 0 -> 25 bytes .../BadDebts/BadDebt.php:Zone.Identifier | Bin 0 -> 25 bytes .../BadDebtDocument.php:Zone.Identifier | Bin 0 -> 25 bytes .../BadDebts/BadDebtMemo.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Boards/Board.php:Zone.Identifier | Bin 0 -> 25 bytes .../Boards/BoardComment.php:Zone.Identifier | Bin 0 -> 25 bytes .../Boards/BoardSetting.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Boards/Post.php:Zone.Identifier | Bin 0 -> 25 bytes .../PostCustomFieldValue.php:Zone.Identifier | Bin 0 -> 25 bytes .../CalculationConfig.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/CategoryGroup.php:Zone.Identifier | Bin 0 -> 25 bytes .../Commons/Category.php:Zone.Identifier | Bin 0 -> 25 bytes .../Commons/CategoryField.php:Zone.Identifier | Bin 0 -> 25 bytes .../Commons/CategoryLog.php:Zone.Identifier | Bin 0 -> 25 bytes .../CategoryTemplate.php:Zone.Identifier | Bin 0 -> 25 bytes .../Classification.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Commons/File.php:Zone.Identifier | Bin 0 -> 25 bytes .../Commons/GlobalMenu.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Commons/Menu.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Commons/Tag.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/CompanyRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../Construction/Contract.php:Zone.Identifier | Bin 0 -> 25 bytes .../Design/BomTemplate.php:Zone.Identifier | Bin 0 -> 25 bytes .../BomTemplateItem.php:Zone.Identifier | Bin 0 -> 25 bytes .../Design/DesignModel.php:Zone.Identifier | Bin 0 -> 25 bytes .../Design/ModelVersion.php:Zone.Identifier | Bin 0 -> 25 bytes .../Estimate/Estimate.php:Zone.Identifier | Bin 0 -> 25 bytes .../Estimate/EstimateItem.php:Zone.Identifier | Bin 0 -> 25 bytes .../MainRequestEstimate.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/FcmSendLog.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/FileShareLink.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Folder.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemMaster/CustomTab.php:Zone.Identifier | Bin 0 -> 25 bytes .../EntityRelationship.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemBomItem.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemMaster/ItemField.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemMaster/ItemPage.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemSection.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemMaster/TabColumn.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemMaster/UnitOption.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Items/Item.php:Zone.Identifier | Bin 0 -> 25 bytes .../Items/ItemDetail.php:Zone.Identifier | Bin 0 -> 25 bytes .../Items/ItemReceipt.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/LoginToken.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/MainRequest.php:Zone.Identifier | Bin 0 -> 25 bytes .../MainRequestFlow.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Materials/Material.php | 79 ++ .../Materials/Material.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Materials/MaterialInspection.php | 26 + .../MaterialInspection.php:Zone.Identifier | Bin 0 -> 25 bytes .../Materials/MaterialInspectionItem.php | 20 + ...MaterialInspectionItem.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Materials/MaterialReceipt.php | 32 + .../MaterialReceipt.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Members/User.php:Zone.Identifier | Bin 0 -> 25 bytes .../UserMenuPermission.php:Zone.Identifier | Bin 0 -> 25 bytes .../Members/UserRole.php:Zone.Identifier | Bin 0 -> 25 bytes .../Members/UserTenant.php:Zone.Identifier | Bin 0 -> 25 bytes .../NotificationSetting.php:Zone.Identifier | Bin 0 -> 25 bytes ...tificationSettingGroup.php:Zone.Identifier | Bin 0 -> 25 bytes ...cationSettingGroupItem.php:Zone.Identifier | Bin 0 -> 25 bytes ...ationSettingGroupState.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Orders/Client.php:Zone.Identifier | Bin 0 -> 25 bytes .../Orders/ClientGroup.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Orders/Order.php:Zone.Identifier | Bin 0 -> 25 bytes .../Orders/OrderHistory.php:Zone.Identifier | Bin 0 -> 25 bytes .../Orders/OrderItem.php:Zone.Identifier | Bin 0 -> 25 bytes .../OrderItemComponent.php:Zone.Identifier | Bin 0 -> 25 bytes .../Orders/OrderVersion.php:Zone.Identifier | Bin 0 -> 25 bytes .../Permission.php:Zone.Identifier | Bin 0 -> 25 bytes .../PermissionOverride.php:Zone.Identifier | Bin 0 -> 25 bytes .../Permissions/Role.php:Zone.Identifier | Bin 0 -> 25 bytes .../RoleMenuPermission.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Popups/Popup.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Process.php:Zone.Identifier | Bin 0 -> 25 bytes ...cessClassificationRule.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/ProcessItem.php:Zone.Identifier | Bin 0 -> 25 bytes .../Production/WorkOrder.php:Zone.Identifier | Bin 0 -> 25 bytes .../WorkOrderAssignee.php:Zone.Identifier | Bin 0 -> 25 bytes ...WorkOrderBendingDetail.php:Zone.Identifier | Bin 0 -> 25 bytes .../WorkOrderIssue.php:Zone.Identifier | Bin 0 -> 25 bytes .../WorkOrderItem.php:Zone.Identifier | Bin 0 -> 25 bytes .../Production/WorkResult.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Products/CommonCode.php | 47 + .../Products/CommonCode.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Products/Part.php | 33 + app/Models/Products/Part.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Products/Price.php:Zone.Identifier | Bin 0 -> 25 bytes .../PriceRevision.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Products/Product.php | 118 ++ .../Products/Product.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Products/ProductComponent.php | 115 ++ .../ProductComponent.php:Zone.Identifier | Bin 0 -> 25 bytes .../PushDeviceToken.php:Zone.Identifier | Bin 0 -> 25 bytes ...ushNotificationSetting.php:Zone.Identifier | Bin 0 -> 25 bytes .../Qualitys/Inspection.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Qualitys/Lot.php:Zone.Identifier | Bin 0 -> 25 bytes .../Qualitys/LotSale.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Quote/Quote.php:Zone.Identifier | Bin 0 -> 25 bytes .../Quote/QuoteFormula.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteFormulaCategory.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteFormulaItem.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteFormulaMapping.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteFormulaRange.php:Zone.Identifier | Bin 0 -> 25 bytes .../Quote/QuoteItem.php:Zone.Identifier | Bin 0 -> 25 bytes .../Quote/QuoteRevision.php:Zone.Identifier | Bin 0 -> 25 bytes .../Scopes/TenantScope.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/SiteAdmin.php:Zone.Identifier | Bin 0 -> 25 bytes .../SystemFieldDefinition.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/AiReport.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/Approval.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/ApprovalForm.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/ApprovalLine.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/ApprovalStep.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/Attendance.php:Zone.Identifier | Bin 0 -> 25 bytes .../AttendanceSetting.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/BankAccount.php:Zone.Identifier | Bin 0 -> 25 bytes .../BarobillSetting.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Tenants/Bill.php:Zone.Identifier | Bin 0 -> 25 bytes .../BillInstallment.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Tenants/Card.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/DataExport.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/Department.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/Deposit.php:Zone.Identifier | Bin 0 -> 25 bytes .../ExpectedExpense.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Tenants/Leave.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/LeaveBalance.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/LeaveGrant.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/LeavePolicy.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Tenants/Loan.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/Payment.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/Payroll.php:Zone.Identifier | Bin 0 -> 25 bytes .../PayrollSetting.php:Zone.Identifier | Bin 0 -> 25 bytes .../Pivots/DepartmentUser.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Tenants/Plan.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/Position.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/Purchase.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/Receiving.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Tenants/Salary.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Tenants/Sale.php:Zone.Identifier | Bin 0 -> 25 bytes .../SettingFieldDef.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/Shipment.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/ShipmentItem.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Tenants/Site.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Tenants/Stock.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/StockLot.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/Subscription.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/TaxInvoice.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/Tenants/Tenant.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantFieldSetting.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantOptionGroup.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantOptionValue.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantStatField.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantUserProfile.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/Withdrawal.php:Zone.Identifier | Bin 0 -> 25 bytes .../Tenants/WorkSetting.php:Zone.Identifier | Bin 0 -> 25 bytes app/Models/UserInvitation.php:Zone.Identifier | Bin 0 -> 25 bytes .../MenuObserver.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantObserver.php:Zone.Identifier | Bin 0 -> 25 bytes .../AppServiceProvider.php:Zone.Identifier | Bin 0 -> 25 bytes ...grationServiceProvider.php:Zone.Identifier | Bin 0 -> 25 bytes .../MainRequestRepository.php:Zone.Identifier | Bin 0 -> 25 bytes .../AccountService.php:Zone.Identifier | Bin 0 -> 25 bytes .../AdminFcmService.php:Zone.Identifier | Bin 0 -> 25 bytes ...AdminPermissionService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/AdminService.php:Zone.Identifier | Bin 0 -> 25 bytes .../AiReportService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ApprovalService.php:Zone.Identifier | Bin 0 -> 25 bytes .../AttendanceService.php:Zone.Identifier | Bin 0 -> 25 bytes .../Audit/AuditLogService.php:Zone.Identifier | Bin 0 -> 25 bytes .../Audit/AuditLogger.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/AuthService.php:Zone.Identifier | Bin 0 -> 25 bytes .../Authz/AccessService.php:Zone.Identifier | Bin 0 -> 25 bytes .../RolePermissionService.php:Zone.Identifier | Bin 0 -> 25 bytes .../Authz/RoleService.php:Zone.Identifier | Bin 0 -> 25 bytes .../Authz/UserRoleService.php:Zone.Identifier | Bin 0 -> 25 bytes .../BadDebtService.php:Zone.Identifier | Bin 0 -> 25 bytes .../BankAccountService.php:Zone.Identifier | Bin 0 -> 25 bytes ...BankTransactionService.php:Zone.Identifier | Bin 0 -> 25 bytes .../BarobillService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/BillService.php:Zone.Identifier | Bin 0 -> 25 bytes .../Boards/BoardService.php:Zone.Identifier | Bin 0 -> 25 bytes .../Boards/PostService.php:Zone.Identifier | Bin 0 -> 25 bytes .../CalculationEngine.php:Zone.Identifier | Bin 0 -> 25 bytes .../FormulaParser.php:Zone.Identifier | Bin 0 -> 25 bytes .../ParameterValidator.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/CardService.php:Zone.Identifier | Bin 0 -> 25 bytes ...CardTransactionService.php:Zone.Identifier | Bin 0 -> 25 bytes .../CategoryFieldService.php:Zone.Identifier | Bin 0 -> 25 bytes .../CategoryLogService.php:Zone.Identifier | Bin 0 -> 25 bytes .../CategoryService.php:Zone.Identifier | Bin 0 -> 25 bytes ...ategoryTemplateService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ClassificationService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ClientGroupService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ClientService.php:Zone.Identifier | Bin 0 -> 25 bytes .../CompanyService.php:Zone.Identifier | Bin 0 -> 25 bytes ...hensiveAnalysisService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ContractService.php:Zone.Identifier | Bin 0 -> 25 bytes .../DailyReportService.php:Zone.Identifier | Bin 0 -> 25 bytes .../DashboardService.php:Zone.Identifier | Bin 0 -> 25 bytes .../DepartmentService.php:Zone.Identifier | Bin 0 -> 25 bytes .../DepositService.php:Zone.Identifier | Bin 0 -> 25 bytes .../BomCalculationService.php:Zone.Identifier | Bin 0 -> 25 bytes .../BomTemplateService.php:Zone.Identifier | Bin 0 -> 25 bytes .../Design/ModelService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ModelVersionService.php:Zone.Identifier | Bin 0 -> 25 bytes .../EmployeeService.php:Zone.Identifier | Bin 0 -> 25 bytes .../EstimateService.php:Zone.Identifier | Bin 0 -> 25 bytes .../EstimateService.php:Zone.Identifier | Bin 0 -> 25 bytes ...ExpectedExpenseService.php:Zone.Identifier | Bin 0 -> 25 bytes .../Fcm/FcmBatchResult.php:Zone.Identifier | Bin 0 -> 25 bytes .../Fcm/FcmException.php:Zone.Identifier | Bin 0 -> 25 bytes .../Fcm/FcmResponse.php:Zone.Identifier | Bin 0 -> 25 bytes .../Fcm/FcmSender.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/FileService.php:Zone.Identifier | Bin 0 -> 25 bytes .../FileStorageService.php:Zone.Identifier | Bin 0 -> 25 bytes .../FolderService.php:Zone.Identifier | Bin 0 -> 25 bytes .../GlobalMenuService.php:Zone.Identifier | Bin 0 -> 25 bytes .../InternalTokenService.php:Zone.Identifier | Bin 0 -> 25 bytes .../CustomTabService.php:Zone.Identifier | Bin 0 -> 25 bytes ...ityRelationshipService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemBomItemService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemDataService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemFieldService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemMasterService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemPageService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemSectionService.php:Zone.Identifier | Bin 0 -> 25 bytes ...SectionTemplateService.php:Zone.Identifier | Bin 0 -> 25 bytes .../UnitOptionService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/ItemService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/ItemsService.php | 1210 +++++++++++++++++ app/Services/ItemsService.php:Zone.Identifier | Bin 0 -> 25 bytes .../LeavePolicyService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/LeaveService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/LoanService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/MaterialService.php | 519 +++++++ .../MaterialService.php:Zone.Identifier | Bin 0 -> 25 bytes .../MemberService.php:Zone.Identifier | Bin 0 -> 25 bytes .../MenuBootstrapService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/MenuService.php:Zone.Identifier | Bin 0 -> 25 bytes .../MenuSyncService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ModelSetService.php:Zone.Identifier | Bin 0 -> 25 bytes ...ficationSettingService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/OrderService.php:Zone.Identifier | Bin 0 -> 25 bytes .../PaymentService.php:Zone.Identifier | Bin 0 -> 25 bytes .../PayrollService.php:Zone.Identifier | Bin 0 -> 25 bytes .../PermissionService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/PlanService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/PopupService.php:Zone.Identifier | Bin 0 -> 25 bytes .../PositionService.php:Zone.Identifier | Bin 0 -> 25 bytes .../PricingService.php:Zone.Identifier | Bin 0 -> 25 bytes .../PricingService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ProcessService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/ProductBomService.php | 537 ++++++++ .../ProductBomService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/ProductService.php | 362 +++++ .../ProductService.php:Zone.Identifier | Bin 0 -> 25 bytes .../Products/ProductComponentResolver.php | 234 ++++ ...oductComponentResolver.php:Zone.Identifier | Bin 0 -> 25 bytes .../PurchaseService.php:Zone.Identifier | Bin 0 -> 25 bytes ...ushNotificationService.php:Zone.Identifier | Bin 0 -> 25 bytes ...ormulaEvaluatorService.php:Zone.Identifier | Bin 0 -> 25 bytes ...uoteCalculationService.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteDocumentService.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteNumberService.php:Zone.Identifier | Bin 0 -> 25 bytes .../Quote/QuoteService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ReceivablesService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ReceivingService.php:Zone.Identifier | Bin 0 -> 25 bytes .../RegisterService.php:Zone.Identifier | Bin 0 -> 25 bytes .../ReportService.php:Zone.Identifier | Bin 0 -> 25 bytes .../SalaryService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/SaleService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/Service.php:Zone.Identifier | Bin 0 -> 25 bytes .../ShipmentService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/SiteService.php:Zone.Identifier | Bin 0 -> 25 bytes app/Services/StockService.php:Zone.Identifier | Bin 0 -> 25 bytes .../SubscriptionService.php:Zone.Identifier | Bin 0 -> 25 bytes .../TaxInvoiceService.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantBootstrapStep.php:Zone.Identifier | Bin 0 -> 25 bytes .../RecipeRegistry.php:Zone.Identifier | Bin 0 -> 25 bytes ...CapabilityProfilesStep.php:Zone.Identifier | Bin 0 -> 25 bytes .../Steps/CategoriesStep.php:Zone.Identifier | Bin 0 -> 25 bytes .../Steps/MenusStep.php:Zone.Identifier | Bin 0 -> 25 bytes .../Steps/SettingsStep.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantBootstrapLogger.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantBootstrapper.php:Zone.Identifier | Bin 0 -> 25 bytes ...antFieldSettingService.php:Zone.Identifier | Bin 0 -> 25 bytes ...nantOptionGroupService.php:Zone.Identifier | Bin 0 -> 25 bytes ...nantOptionValueService.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantService.php:Zone.Identifier | Bin 0 -> 25 bytes ...TenantStatFieldService.php:Zone.Identifier | Bin 0 -> 25 bytes ...nantUserProfileService.php:Zone.Identifier | Bin 0 -> 25 bytes .../UserInvitationService.php:Zone.Identifier | Bin 0 -> 25 bytes .../VendorLedgerService.php:Zone.Identifier | Bin 0 -> 25 bytes .../WithdrawalService.php:Zone.Identifier | Bin 0 -> 25 bytes .../WorkOrderService.php:Zone.Identifier | Bin 0 -> 25 bytes .../WorkResultService.php:Zone.Identifier | Bin 0 -> 25 bytes .../WorkSettingService.php:Zone.Identifier | Bin 0 -> 25 bytes .../BomItemRules.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/AccountApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/AdminApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/AdminFcmApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/AdminGlobalMenuApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/AiReportApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ApprovalApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ApprovalFormApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ApprovalLineApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/AttendanceApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/AuditLogApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/AuthApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/BadDebtApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/BankAccountApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/BankTransactionApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/BarobillSettingApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/BillApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/BoardApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/BomCalculationApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/CardApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/CardTransactionApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/CategoryApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/CategoryExtras.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ClassificationApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/ClientApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ClientGroupApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/CommonApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/CommonComponents.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/CompanyApi.php:Zone.Identifier | Bin 0 -> 25 bytes ...mprehensiveAnalysisApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ContractApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/DailyReportApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/DashboardApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/DepartmentApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/DepositApi.php:Zone.Identifier | Bin 0 -> 25 bytes ...esignBomTemplateExtras.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/DesignModelApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/EmployeeApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../EntityRelationshipApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/EstimateApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ExpectedExpenseApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/FieldProfileApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/FileApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/FolderApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/InternalApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ItemMasterApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/ItemsApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ItemsBomApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ItemsFileApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/LeaveApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/LeavePolicyApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/LoanApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/MaterialApi.php | 316 +++++ .../v1/MaterialApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/MenuApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/ModelApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ModelSetApi.php:Zone.Identifier | Bin 0 -> 25 bytes ...NotificationSettingApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/OrderApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/PaymentApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/PayrollApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/PermissionApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/PlanApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/PopupApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/PositionApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/PostApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/PricingApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/ProcessApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/ProductApi.php | 780 +++++++++++ app/Swagger/v1/ProductApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/ProductExtraSchemas.php | 178 +++ .../ProductExtraSchemas.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/PurchaseApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/PushApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/QuoteApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ReceivablesApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ReceivingApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/RefreshApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/RegisterApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/ReportApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/RoleApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/RolePermissionApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/SAMInfo.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/SaleApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/ShipmentApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/SiteApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/StockApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/SubscriptionApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/SystemBoardApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/TaxInvoiceApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/TenantApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../TenantFieldSettingApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/TenantStatFieldApi.php:Zone.Identifier | Bin 0 -> 25 bytes app/Swagger/v1/UserApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/UserInvitationApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/UserRoleApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/VendorLedgerApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/WithdrawalApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/WorkOrderApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/WorkResultApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../v1/WorkSettingApi.php:Zone.Identifier | Bin 0 -> 25 bytes .../BelongsToTenant.php:Zone.Identifier | Bin 0 -> 25 bytes app/Traits/LockCheckTrait.php:Zone.Identifier | Bin 0 -> 25 bytes app/Traits/ModelTrait.php:Zone.Identifier | Bin 0 -> 25 bytes .../UppercaseAttributes.php:Zone.Identifier | Bin 0 -> 25 bytes .../Components/AppLayout.php:Zone.Identifier | Bin 0 -> 25 bytes .../GuestLayout.php:Zone.Identifier | Bin 0 -> 25 bytes artisan:Zone.Identifier | Bin 0 -> 25 bytes bootstrap/app.php:Zone.Identifier | Bin 0 -> 25 bytes bootstrap/providers.php:Zone.Identifier | Bin 0 -> 25 bytes composer.json:Zone.Identifier | Bin 0 -> 25 bytes composer.lock:Zone.Identifier | Bin 0 -> 25 bytes config/app.php:Zone.Identifier | Bin 0 -> 25 bytes config/audit.php:Zone.Identifier | Bin 0 -> 25 bytes config/auth.php:Zone.Identifier | Bin 0 -> 25 bytes config/authz.php:Zone.Identifier | Bin 0 -> 25 bytes config/cache.php:Zone.Identifier | Bin 0 -> 25 bytes config/cors.php:Zone.Identifier | Bin 0 -> 25 bytes config/custom.php:Zone.Identifier | Bin 0 -> 25 bytes config/database.php:Zone.Identifier | Bin 0 -> 25 bytes .../er-diagram-generator.php:Zone.Identifier | Bin 0 -> 25 bytes config/fcm.php:Zone.Identifier | Bin 0 -> 25 bytes config/filesystems.php:Zone.Identifier | Bin 0 -> 25 bytes config/l5-swagger.php:Zone.Identifier | Bin 0 -> 25 bytes config/livewire.php:Zone.Identifier | Bin 0 -> 25 bytes config/logging.php:Zone.Identifier | Bin 0 -> 25 bytes config/mail.php:Zone.Identifier | Bin 0 -> 25 bytes config/permission.php:Zone.Identifier | Bin 0 -> 25 bytes config/products.php:Zone.Identifier | Bin 0 -> 25 bytes config/queue.php:Zone.Identifier | Bin 0 -> 25 bytes config/sanctum.php:Zone.Identifier | Bin 0 -> 25 bytes config/services.php:Zone.Identifier | Bin 0 -> 25 bytes config/session.php:Zone.Identifier | Bin 0 -> 25 bytes database/.DS_Store:Zone.Identifier | Bin 0 -> 25 bytes database/.gitignore:Zone.Identifier | Bin 0 -> 25 bytes .../factories/UserFactory.php:Zone.Identifier | Bin 0 -> 25 bytes ...add_tenant_id_to_work_order_sub_tables.php | 88 ++ ..._work_order_sub_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...0000_create_work_order_assignees_table.php | 41 + ..._order_assignees_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...reate_authz_structures.php:Zone.Identifier | Bin 0 -> 25 bytes ...on_for_teams_and_guard.php:Zone.Identifier | Bin 0 -> 25 bytes ..._slug_from_menus_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._parent_id_departments.php:Zone.Identifier | Bin 0 -> 25 bytes ...o_spatie_and_overrides.php:Zone.Identifier | Bin 0 -> 25 bytes ...create_materials_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...oducts_profile_and_bom.php:Zone.Identifier | Bin 0 -> 25 bytes ...t_bootstrap_runs_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._classifications_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...f_type_and_material_id.php:Zone.Identifier | Bin 0 -> 25 bytes ...unit_to_products_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ents_unify_ref_columns.php:Zone.Identifier | Bin 0 -> 25 bytes ...01_create_models_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...e_model_versions_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...te_bom_templates_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...m_template_items_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...o_model_versions_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...reate_audit_logs_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...n_fields_to_bom_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...culation_configs_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ynamic_estimate_fields.php:Zone.Identifier | Bin 0 -> 25 bytes ...create_estimates_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...al_foreign_keys_phase1.php:Zone.Identifier | Bin 0 -> 25 bytes ...te_foreign_keys_phase2.php:Zone.Identifier | Bin 0 -> 25 bytes ...ial_foreign_key_phase3.php:Zone.Identifier | Bin 0 -> 25 bytes ...te_client_groups_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...up_id_to_clients_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._price_histories_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._active_to_users_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...create_prospects_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...reate_demo_links_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...r_admin_to_users_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...varchar_in_users_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...08_enhance_files_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...7_create_folders_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...age_columns_to_tenants.php:Zone.Identifier | Bin 0 -> 25 bytes ...le_deletion_logs_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...file_share_links_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ge_usage_history_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ype_to_materials_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...rchived_records_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...indexes_to_menus_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...elds_to_products_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...oduct_components_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...nant_stat_fields_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...elds_to_products_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...s_and_materials_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...ate_unit_options_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ection_templates_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...em_master_fields_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...reate_item_pages_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...te_item_sections_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...eate_item_fields_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...e_item_bom_items_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...eate_custom_tabs_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...eate_tab_columns_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...udit_columns_to_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ..._to_soft_delete_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...o_independent_entities.php:Zone.Identifier | Bin 0 -> 25 bytes ...ty_relationships_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...o_entity_relationships.php:Zone.Identifier | Bin 0 -> 25 bytes ...in_item_sections_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...tions_and_migrate_data.php:Zone.Identifier | Bin 0 -> 25 bytes ...s_to_item_fields_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...archived_records_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...em_master_fields_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...lumns_from_item_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ..._admin_api_flow_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...ty_relationships_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._type_to_tenants_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...fields_to_boards_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...create_admin_pm_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...s_to_item_fields_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...is_urgent_to_pm_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...record_type_to_varchar.php:Zone.Identifier | Bin 0 -> 25 bytes ...id_to_archived_records.php:Zone.Identifier | Bin 0 -> 25 bytes ...n_pm_daily_logs_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...assword_to_users_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...columns_to_menus_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ate_global_menus_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._admin_pm_issues_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...et_category_id_default.php:Zone.Identifier | Bin 0 -> 25 bytes ...e_category_id_nullable.php:Zone.Identifier | Bin 0 -> 25 bytes ..._admin_pm_issues_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...in_api_flow_runs_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...e_quote_formula_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...in_api_flow_runs_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ields_to_clients_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...42_create_quotes_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ields_to_clients_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...n_to_item_fields_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...33_create_prices_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._price_revisions_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ce_histories_to_prices.php:Zone.Identifier | Bin 0 -> 25 bytes ..._price_histories_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...le_to_item_pages_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...s_to_item_fields_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...s_is_active_to_boolean.php:Zone.Identifier | Bin 0 -> 25 bytes ...nt_user_profiles_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...eate_attendances_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...s_to_attendances_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...lumn_to_products_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...elds_unique_constraint.php:Zone.Identifier | Bin 0 -> 25 bytes ...lumn_to_products_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...000_create_items_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...item_id_mappings_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...cts_materials_to_items.php:Zone.Identifier | Bin 0 -> 25 bytes ...llback_items_migration.php:Zone.Identifier | Bin 0 -> 25 bytes ...y_and_change_file_type.php:Zone.Identifier | Bin 0 -> 25 bytes ...pes_before_unification.php:Zone.Identifier | Bin 0 -> 25 bytes ...507_create_items_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ate_item_details_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...cts_materials_to_items.php:Zone.Identifier | Bin 0 -> 25 bytes ..._source_table_to_items.php:Zone.Identifier | Bin 0 -> 25 bytes ...erence_tables_to_items.php:Zone.Identifier | Bin 0 -> 25 bytes ...em_ids_to_new_item_ids.php:Zone.Identifier | Bin 0 -> 25 bytes ...s_and_materials_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...ct_material_id_columns.php:Zone.Identifier | Bin 0 -> 25 bytes ..._group_to_common_codes.php:Zone.Identifier | Bin 0 -> 25 bytes ...api_request_logs_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...api_request_logs_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...options_to_menus_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._create_biz_cert_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...min_meeting_logs_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ield_definitions_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...00_create_leaves_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...e_approval_forms_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...e_leave_balances_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...001_create_sales_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...e_approval_lines_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...create_purchases_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...create_approvals_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...e_approval_steps_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...te_work_settings_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...endance_settings_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...002_create_sites_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...000_create_cards_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...te_bank_accounts_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._create_deposits_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...eate_withdrawals_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...in_api_bookmarks_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...in_api_templates_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...in_api_histories_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...api_environments_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._create_payrolls_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...sh_device_tokens_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...payroll_settings_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ication_settings_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...001_create_loans_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...reate_ai_reports_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...api_deprecations_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...arobill_settings_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ate_tax_invoices_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._to_push_device_tokens.php:Zone.Identifier | Bin 0 -> 25 bytes ...te_fcm_send_logs_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...user_invitations_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ication_settings_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...create_bad_debts_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...d_debt_documents_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...e_bad_debt_memos_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ate_data_exports_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...01_create_popups_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ield_definitions_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ate_login_tokens_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._codes_to_common_codes.php:Zone.Identifier | Bin 0 -> 25 bytes ...lients_enum_to_varchar.php:Zone.Identifier | Bin 0 -> 25 bytes ...de_to_actual_item_type.php:Zone.Identifier | Bin 0 -> 25 bytes ...common_codes_item_type.php:Zone.Identifier | Bin 0 -> 25 bytes ...company_requests_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._setting_groups_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...ments_paid_at_nullable.php:Zone.Identifier | Bin 0 -> 25 bytes ...to_subscriptions_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...000_create_bills_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...mns_from_clients_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...e_flags_to_sales_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ved_to_purchases_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ate_leave_grants_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._create_salaries_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...xpected_expenses_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...eate_work_orders_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...e_leave_policies_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...work_order_items_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._bending_details_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ork_order_issues_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...reate_receivings_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...06_create_stocks_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...reate_stock_lots_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...s_to_withdrawals_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ate_work_results_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...create_shipments_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...e_shipment_items_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...create_processes_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...lumns_to_clients_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...ype_to_purchases_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...tem_id_to_stocks_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...legacy_material_tables.php:Zone.Identifier | Bin 0 -> 25 bytes ...create_positions_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...n_type_to_common_codes.php:Zone.Identifier | Bin 0 -> 25 bytes ...key_to_positions_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._hidden_to_roles_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...erdue_to_clients_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...s_to_order_items_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...fields_to_orders_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...der_id_to_quotes_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...create_contracts_table.php:Zone.Identifier | Bin 0 -> 25 bytes ...te_process_items_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._fields_to_sites_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._codes_to_common_codes.php:Zone.Identifier | Bin 0 -> 25 bytes ...001_add_columns_to_bank_accounts_table.php | 53 + ...to_bank_accounts_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._100002_create_bank_transactions_table.php | 72 + ...ank_transactions_table.php:Zone.Identifier | Bin 0 -> 25 bytes ..._20_110001_create_fund_schedules_table.php | 75 + ...e_fund_schedules_table.php:Zone.Identifier | Bin 0 -> 25 bytes .../schema/mysql-schema.sql:Zone.Identifier | Bin 0 -> 25 bytes ...ApprovalTestDataSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes database/seeders/BankAccountSeeder.php | 282 ++++ .../BankAccountSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...esCategoryFieldsSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...TenantStatFieldsSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...apabilityProfileSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../CategorySeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...ehensiveAnalysisSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DatabaseSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DemoSystemSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummyAttendanceSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...ttendanceSettingSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummyBadDebtSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...DummyBankAccountSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../Dummy/DummyBillSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../Dummy/DummyCardSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...DummyClientGroupSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummyClientSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummyDepartmentSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummyDepositSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../Dummy/DummyItemSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummyLeaveGrantSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummyLeaveSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummyPaymentSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummyPopupSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummyPurchaseSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummySalarySeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../Dummy/DummySaleSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../Dummy/DummyUserSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummyWithdrawalSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...DummyWorkSettingSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../DummyDataSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../seeders/FolderSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes database/seeders/FundScheduleSeeder.php | 160 +++ .../FundScheduleSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...obalMenuTemplateSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemMasterSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../ItemTypeSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../PositionSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...eFormulaCategorySeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...QuoteFormulaItemSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...teFormulaMappingSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../QuoteFormulaSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../ReactMenuSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes .../StockReceivingSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes ...mFieldDefinitionSeeder.php:Zone.Identifier | Bin 0 -> 25 bytes lang/en/employee.php:Zone.Identifier | Bin 0 -> 25 bytes lang/en/error.php:Zone.Identifier | Bin 0 -> 25 bytes lang/en/message.php:Zone.Identifier | Bin 0 -> 25 bytes lang/ko/employee.php:Zone.Identifier | Bin 0 -> 25 bytes lang/ko/error.php:Zone.Identifier | Bin 0 -> 25 bytes lang/ko/message.php:Zone.Identifier | Bin 0 -> 25 bytes lang/ko/validation.php:Zone.Identifier | Bin 0 -> 25 bytes package-lock.json:Zone.Identifier | Bin 0 -> 25 bytes package.json:Zone.Identifier | Bin 0 -> 25 bytes phpunit.xml:Zone.Identifier | Bin 0 -> 25 bytes postcss.config.js:Zone.Identifier | Bin 0 -> 25 bytes pre-receive.bak:Zone.Identifier | Bin 0 -> 25 bytes public/.DS_Store:Zone.Identifier | Bin 0 -> 25 bytes public/.htaccess:Zone.Identifier | Bin 0 -> 25 bytes .../css/animate.delay.css:Zone.Identifier | Bin 0 -> 25 bytes .../admin/css/animate.min.css:Zone.Identifier | Bin 0 -> 25 bytes ...otstrap-fileupload.min.css:Zone.Identifier | Bin 0 -> 25 bytes .../bootstrap-override.css:Zone.Identifier | Bin 0 -> 25 bytes ...otstrap-timepicker.min.css:Zone.Identifier | Bin 0 -> 25 bytes .../admin/css/bootstrap.css:Zone.Identifier | Bin 0 -> 25 bytes .../css/bootstrap.min.css:Zone.Identifier | Bin 0 -> 25 bytes public/admin/css/chosen.css:Zone.Identifier | Bin 0 -> 25 bytes public/admin/css/custom.css:Zone.Identifier | Bin 0 -> 25 bytes .../css/font-awesome.css:Zone.Identifier | Bin 0 -> 25 bytes .../css/font-awesome.min.css:Zone.Identifier | Bin 0 -> 25 bytes .../css/jquery-ui-1.10.3.css:Zone.Identifier | Bin 0 -> 25 bytes .../css/jquery.datatables.css:Zone.Identifier | Bin 0 -> 25 bytes public/admin/css/lato.css:Zone.Identifier | Bin 0 -> 25 bytes public/admin/css/layout.css:Zone.Identifier | Bin 0 -> 25 bytes public/admin/css/roboto.css:Zone.Identifier | Bin 0 -> 25 bytes .../css/style.default.css:Zone.Identifier | Bin 0 -> 25 bytes .../css/style.inverse.css:Zone.Identifier | Bin 0 -> 25 bytes .../admin/css/style_leave.css:Zone.Identifier | Bin 0 -> 25 bytes .../admin/css/style_login.css:Zone.Identifier | Bin 0 -> 25 bytes .../tablesorter_2.31.3.css:Zone.Identifier | Bin 0 -> 25 bytes public/admin/css/toggles.css:Zone.Identifier | Bin 0 -> 25 bytes .../css/font-awesome.css:Zone.Identifier | Bin 0 -> 25 bytes .../css/font-awesome.min.css:Zone.Identifier | Bin 0 -> 25 bytes .../fonts/FontAwesome.otf:Zone.Identifier | Bin 0 -> 25 bytes .../fontawesome-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../fontawesome-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../fontawesome-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../fontawesome-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../less/bordered-pulled.less:Zone.Identifier | Bin 0 -> 25 bytes .../less/core.less:Zone.Identifier | Bin 0 -> 25 bytes .../less/fixed-width.less:Zone.Identifier | Bin 0 -> 25 bytes .../less/font-awesome.less:Zone.Identifier | Bin 0 -> 25 bytes .../less/icons.less:Zone.Identifier | Bin 0 -> 25 bytes .../less/larger.less:Zone.Identifier | Bin 0 -> 25 bytes .../less/list.less:Zone.Identifier | Bin 0 -> 25 bytes .../less/mixins.less:Zone.Identifier | Bin 0 -> 25 bytes .../less/path.less:Zone.Identifier | Bin 0 -> 25 bytes .../less/rotated-flipped.less:Zone.Identifier | Bin 0 -> 25 bytes .../less/spinning.less:Zone.Identifier | Bin 0 -> 25 bytes .../less/stacked.less:Zone.Identifier | Bin 0 -> 25 bytes .../less/variables.less:Zone.Identifier | Bin 0 -> 25 bytes .../_bordered-pulled.scss:Zone.Identifier | Bin 0 -> 25 bytes .../scss/_core.scss:Zone.Identifier | Bin 0 -> 25 bytes .../scss/_fixed-width.scss:Zone.Identifier | Bin 0 -> 25 bytes .../scss/_icons.scss:Zone.Identifier | Bin 0 -> 25 bytes .../scss/_larger.scss:Zone.Identifier | Bin 0 -> 25 bytes .../scss/_list.scss:Zone.Identifier | Bin 0 -> 25 bytes .../scss/_mixins.scss:Zone.Identifier | Bin 0 -> 25 bytes .../scss/_path.scss:Zone.Identifier | Bin 0 -> 25 bytes .../_rotated-flipped.scss:Zone.Identifier | Bin 0 -> 25 bytes .../scss/_spinning.scss:Zone.Identifier | Bin 0 -> 25 bytes .../scss/_stacked.scss:Zone.Identifier | Bin 0 -> 25 bytes .../scss/_variables.scss:Zone.Identifier | Bin 0 -> 25 bytes .../scss/font-awesome.scss:Zone.Identifier | Bin 0 -> 25 bytes .../fonts/FontAwesome.otf:Zone.Identifier | Bin 0 -> 25 bytes .../fontawesome-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../fontawesome-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../fontawesome-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../fontawesome-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes ...cons-halflings-regular.eot:Zone.Identifier | Bin 0 -> 25 bytes ...cons-halflings-regular.svg:Zone.Identifier | Bin 0 -> 25 bytes ...cons-halflings-regular.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...ons-halflings-regular.woff:Zone.Identifier | Bin 0 -> 25 bytes public/admin/fonts/index.html:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Bla-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Bla-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Bla-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-Bla-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-BlaIta-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-BlaIta-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-BlaIta-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-BlaIta-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Bol-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Bol-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Bol-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-Bol-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-BolIta-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-BolIta-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-BolIta-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-BolIta-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Hai-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Hai-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Hai-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-Hai-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-HaiIta-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-HaiIta-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-HaiIta-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-HaiIta-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Lig-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Lig-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Lig-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-Lig-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-LigIta-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-LigIta-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-LigIta-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-LigIta-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Reg-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Reg-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../lato/Lato-Reg-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-Reg-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-RegIta-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-RegIta-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-RegIta-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Lato-RegIta-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes ... Open Font License 1.1.txt:Zone.Identifier | Bin 0 -> 25 bytes .../fonts/lato/index.html:Zone.Identifier | Bin 0 -> 25 bytes ...Google Android License.txt:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Black-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Black-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Black-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Black-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes ...to-BlackItalic-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes ...to-BlackItalic-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes ...to-BlackItalic-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...o-BlackItalic-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Bold-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Bold-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Bold-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Bold-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes ...-BoldCondensed-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes ...-BoldCondensed-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes ...-BoldCondensed-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...BoldCondensed-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes ...ondensedItalic-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes ...ondensedItalic-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes ...ondensedItalic-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...ndensedItalic-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes ...oto-BoldItalic-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes ...oto-BoldItalic-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes ...oto-BoldItalic-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...to-BoldItalic-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes ...boto-Condensed-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes ...boto-Condensed-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes ...boto-Condensed-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...oto-Condensed-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes ...ondensedItalic-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes ...ondensedItalic-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes ...ondensedItalic-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...ndensedItalic-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Italic-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Italic-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Italic-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...Roboto-Italic-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Light-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Light-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Light-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Light-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes ...to-LightItalic-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes ...to-LightItalic-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes ...to-LightItalic-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...o-LightItalic-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Medium-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Medium-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Medium-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...Roboto-Medium-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes ...o-MediumItalic-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes ...o-MediumItalic-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes ...o-MediumItalic-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...-MediumItalic-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes ...Roboto-Regular-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes ...Roboto-Regular-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes ...Roboto-Regular-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...oboto-Regular-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Thin-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Thin-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Thin-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes .../Roboto-Thin-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes ...oto-ThinItalic-webfont.eot:Zone.Identifier | Bin 0 -> 25 bytes ...oto-ThinItalic-webfont.svg:Zone.Identifier | Bin 0 -> 25 bytes ...oto-ThinItalic-webfont.ttf:Zone.Identifier | Bin 0 -> 25 bytes ...to-ThinItalic-webfont.woff:Zone.Identifier | Bin 0 -> 25 bytes .../fonts/roboto/index.html:Zone.Identifier | Bin 0 -> 25 bytes .../fonts/roboto/roboto.css:Zone.Identifier | Bin 0 -> 25 bytes .../admin/images/box_line.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/box_line@2x.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/calendar-arrow.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/chosen-sprite.png:Zone.Identifier | Bin 0 -> 25 bytes .../chosen-sprite@2x.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/close-white.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/dropdown-arrow.png:Zone.Identifier | Bin 0 -> 25 bytes .../admin/images/favicon.png:Zone.Identifier | Bin 0 -> 25 bytes .../admin/images/hormenu.jpg:Zone.Identifier | Bin 0 -> 25 bytes .../images/icon-search.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/icon-search@2x.png:Zone.Identifier | Bin 0 -> 25 bytes .../admin/images/index.html:Zone.Identifier | Bin 0 -> 25 bytes .../images/is-document.png:Zone.Identifier | Bin 0 -> 25 bytes .../admin/images/is-money.png:Zone.Identifier | Bin 0 -> 25 bytes .../admin/images/is-user.png:Zone.Identifier | Bin 0 -> 25 bytes .../admin/images/locked.png:Zone.Identifier | Bin 0 -> 25 bytes public/admin/images/minus.png:Zone.Identifier | Bin 0 -> 25 bytes .../admin/images/minus@2x.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/plus-white.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/plus-white@2x.png:Zone.Identifier | Bin 0 -> 25 bytes public/admin/images/plus.png:Zone.Identifier | Bin 0 -> 25 bytes .../admin/images/plus@2x.png:Zone.Identifier | Bin 0 -> 25 bytes .../admin/images/screen.png:Zone.Identifier | Bin 0 -> 25 bytes .../admin/images/sort_asc.png:Zone.Identifier | Bin 0 -> 25 bytes .../sort_asc_disabled.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/sort_both.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/sort_desc.png:Zone.Identifier | Bin 0 -> 25 bytes .../sort_desc_disabled.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/spritemap.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/spritemap@2x.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/themeforest.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/themepixels.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/uploadfile.png:Zone.Identifier | Bin 0 -> 25 bytes .../images/uploadfile@2x.png:Zone.Identifier | Bin 0 -> 25 bytes public/admin/images/user.png:Zone.Identifier | Bin 0 -> 25 bytes .../admin/js/board/board.js:Zone.Identifier | Bin 0 -> 25 bytes ...ootstrap-fileupload.min.js:Zone.Identifier | Bin 0 -> 25 bytes ...ootstrap-timepicker.min.js:Zone.Identifier | Bin 0 -> 25 bytes public/admin/js/bootstrap.js:Zone.Identifier | Bin 0 -> 25 bytes .../admin/js/bootstrap.min.js:Zone.Identifier | Bin 0 -> 25 bytes .../js/chosen.jquery.min.js:Zone.Identifier | Bin 0 -> 25 bytes .../js/company/company.js:Zone.Identifier | Bin 0 -> 25 bytes public/admin/js/custom.js:Zone.Identifier | Bin 0 -> 25 bytes .../code/accessibility.js.map:Zone.Identifier | Bin 0 -> 25 bytes .../code/accessibility.js:Zone.Identifier | Bin 0 -> 25 bytes .../code/accessibility.src.js:Zone.Identifier | Bin 0 -> 25 bytes .../code/export-data.js.map:Zone.Identifier | Bin 0 -> 25 bytes .../code/export-data.js:Zone.Identifier | Bin 0 -> 25 bytes .../code/export-data.src.js:Zone.Identifier | Bin 0 -> 25 bytes .../code/exporting.js.map:Zone.Identifier | Bin 0 -> 25 bytes .../code/exporting.js:Zone.Identifier | Bin 0 -> 25 bytes .../code/exporting.src.js:Zone.Identifier | Bin 0 -> 25 bytes .../code/pattern-fill.js.map:Zone.Identifier | Bin 0 -> 25 bytes .../code/pattern-fill.js:Zone.Identifier | Bin 0 -> 25 bytes .../code/pattern-fill.src.js:Zone.Identifier | Bin 0 -> 25 bytes .../highcharts-gantt.js.map:Zone.Identifier | Bin 0 -> 25 bytes .../highcharts-gantt.js:Zone.Identifier | Bin 0 -> 25 bytes .../highcharts-gantt.src.js:Zone.Identifier | Bin 0 -> 25 bytes .../highchart/highcharts.js:Zone.Identifier | Bin 0 -> 25 bytes public/admin/js/highcharts.js:Zone.Identifier | Bin 0 -> 25 bytes .../js/jquery-1.10.2.min.js:Zone.Identifier | Bin 0 -> 25 bytes ...query-migrate-1.2.1.min.js:Zone.Identifier | Bin 0 -> 25 bytes .../jquery-ui-1.10.3.min.js:Zone.Identifier | Bin 0 -> 25 bytes .../js/jquery.cookies.js:Zone.Identifier | Bin 0 -> 25 bytes .../jquery.sparkline.min.js:Zone.Identifier | Bin 0 -> 25 bytes .../js/main/dashboard.js:Zone.Identifier | Bin 0 -> 25 bytes .../js/meeting/mtg_mn.js:Zone.Identifier | Bin 0 -> 25 bytes .../admin/js/member/member.js:Zone.Identifier | Bin 0 -> 25 bytes .../admin/js/modernizr.min.js:Zone.Identifier | Bin 0 -> 25 bytes public/admin/js/plan/daily.js:Zone.Identifier | Bin 0 -> 25 bytes public/admin/js/plan/info.js:Zone.Identifier | Bin 0 -> 25 bytes public/admin/js/retina.min.js:Zone.Identifier | Bin 0 -> 25 bytes .../js/screenfull.min.js:Zone.Identifier | Bin 0 -> 25 bytes .../admin/js/stats/common.js:Zone.Identifier | Bin 0 -> 25 bytes .../js/status/daily-list.js:Zone.Identifier | Bin 0 -> 25 bytes .../js/status/task-list.js:Zone.Identifier | Bin 0 -> 25 bytes .../admin/js/toggles.min.js:Zone.Identifier | Bin 0 -> 25 bytes public/api-docs/index.html:Zone.Identifier | Bin 0 -> 25 bytes .../cicd-pipeline-flow.html:Zone.Identifier | Bin 0 -> 25 bytes .../disaster-recovery-plan.md:Zone.Identifier | Bin 0 -> 25 bytes public/develop/index.php:Zone.Identifier | Bin 0 -> 25 bytes ...-presentation-summary.html:Zone.Identifier | Bin 0 -> 25 bytes ...work-topology-diagram.html:Zone.Identifier | Bin 0 -> 25 bytes ...er-spec-cost-analysis.html:Zone.Identifier | Bin 0 -> 25 bytes ...-architecture-diagram.html:Zone.Identifier | Bin 0 -> 25 bytes public/favicon.ico:Zone.Identifier | Bin 0 -> 25 bytes public/html/.DS_Store:Zone.Identifier | Bin 0 -> 25 bytes public/html/inc/footer.php:Zone.Identifier | Bin 0 -> 25 bytes public/html/inc/header.php:Zone.Identifier | Bin 0 -> 25 bytes public/html/pages/home.html:Zone.Identifier | Bin 0 -> 25 bytes public/index.php:Zone.Identifier | Bin 0 -> 25 bytes public/robots.txt:Zone.Identifier | Bin 0 -> 25 bytes public/storage:Zone.Identifier | Bin 0 -> 25 bytes .../favicon-16x16.png:Zone.Identifier | Bin 0 -> 25 bytes .../favicon-32x32.png:Zone.Identifier | Bin 0 -> 25 bytes public/swagger-ui/index.css:Zone.Identifier | Bin 0 -> 25 bytes public/swagger-ui/index.html:Zone.Identifier | Bin 0 -> 25 bytes .../oauth2-redirect.html:Zone.Identifier | Bin 0 -> 25 bytes .../swagger-initializer.js:Zone.Identifier | Bin 0 -> 25 bytes .../swagger-ui-bundle.js.map:Zone.Identifier | Bin 0 -> 25 bytes .../swagger-ui-bundle.js:Zone.Identifier | Bin 0 -> 25 bytes ...r-ui-es-bundle-core.js.map:Zone.Identifier | Bin 0 -> 25 bytes ...agger-ui-es-bundle-core.js:Zone.Identifier | Bin 0 -> 25 bytes ...wagger-ui-es-bundle.js.map:Zone.Identifier | Bin 0 -> 25 bytes .../swagger-ui-es-bundle.js:Zone.Identifier | Bin 0 -> 25 bytes ...i-standalone-preset.js.map:Zone.Identifier | Bin 0 -> 25 bytes ...er-ui-standalone-preset.js:Zone.Identifier | Bin 0 -> 25 bytes .../swagger-ui.css.map:Zone.Identifier | Bin 0 -> 25 bytes .../swagger-ui/swagger-ui.css:Zone.Identifier | Bin 0 -> 25 bytes .../swagger-ui.js.map:Zone.Identifier | Bin 0 -> 25 bytes .../swagger-ui/swagger-ui.js:Zone.Identifier | Bin 0 -> 25 bytes .../api/login_process.php:Zone.Identifier | Bin 0 -> 25 bytes .../api/register_process.php:Zone.Identifier | Bin 0 -> 25 bytes .../approval/instances.php:Zone.Identifier | Bin 0 -> 25 bytes .../approval/objects.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/approval/pool.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/approval/rules.php:Zone.Identifier | Bin 0 -> 25 bytes .../js/permission_menu.js:Zone.Identifier | Bin 0 -> 25 bytes .../category_list.php:Zone.Identifier | Bin 0 -> 25 bytes .../subcategory_list.php:Zone.Identifier | Bin 0 -> 25 bytes public/tenant/inc/config.php:Zone.Identifier | Bin 0 -> 25 bytes public/tenant/inc/footer.php:Zone.Identifier | Bin 0 -> 25 bytes public/tenant/inc/header.php:Zone.Identifier | Bin 0 -> 25 bytes public/tenant/inc/navi.php:Zone.Identifier | Bin 0 -> 25 bytes public/tenant/index.php:Zone.Identifier | Bin 0 -> 25 bytes .../inventory/defective.php:Zone.Identifier | Bin 0 -> 25 bytes .../inventory/stock.php:Zone.Identifier | Bin 0 -> 25 bytes .../inspection_list.php:Zone.Identifier | Bin 0 -> 25 bytes .../inventory_status.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/material/list.php:Zone.Identifier | Bin 0 -> 25 bytes .../member/dashboard.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/member/intro.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/member/login.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/member/logout.php:Zone.Identifier | Bin 0 -> 25 bytes .../member/profile_edit.php:Zone.Identifier | Bin 0 -> 25 bytes .../member/register.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant_add_process.php:Zone.Identifier | Bin 0 -> 25 bytes .../member/tenant_select.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant_select_process.php:Zone.Identifier | Bin 0 -> 25 bytes .../member/withdraw.php:Zone.Identifier | Bin 0 -> 25 bytes public/tenant/order/edit.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/order/estimate.php:Zone.Identifier | Bin 0 -> 25 bytes .../order/estimate_form.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/order/manage.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/order/status.php:Zone.Identifier | Bin 0 -> 25 bytes .../permission/analyze.php:Zone.Identifier | Bin 0 -> 25 bytes .../permission/approver.php:Zone.Identifier | Bin 0 -> 25 bytes .../permission/audit.php:Zone.Identifier | Bin 0 -> 25 bytes .../permission/department.php:Zone.Identifier | Bin 0 -> 25 bytes .../permission/role.php:Zone.Identifier | Bin 0 -> 25 bytes .../permission/structure.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant_menu.php:Zone.Identifier | Bin 0 -> 25 bytes .../permission/user.php:Zone.Identifier | Bin 0 -> 25 bytes .../process/process_form.php:Zone.Identifier | Bin 0 -> 25 bytes .../process_settings.php:Zone.Identifier | Bin 0 -> 25 bytes .../process/processes.php:Zone.Identifier | Bin 0 -> 25 bytes .../process/task_form.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/process/tasks.php:Zone.Identifier | Bin 0 -> 25 bytes .../product/bending.php:Zone.Identifier | Bin 0 -> 25 bytes public/tenant/product/bom.php:Zone.Identifier | Bin 0 -> 25 bytes .../product/bom_combined.php:Zone.Identifier | Bin 0 -> 25 bytes .../product/bom_editor.php:Zone.Identifier | Bin 0 -> 25 bytes .../product/code_lot.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/product/model.php:Zone.Identifier | Bin 0 -> 25 bytes .../product/model_list.php:Zone.Identifier | Bin 0 -> 25 bytes .../product/product_price.php:Zone.Identifier | Bin 0 -> 25 bytes .../production/bend_work.php:Zone.Identifier | Bin 0 -> 25 bytes .../mid_inspection.php:Zone.Identifier | Bin 0 -> 25 bytes .../process_detail.php:Zone.Identifier | Bin 0 -> 25 bytes .../screen_progress.php:Zone.Identifier | Bin 0 -> 25 bytes .../screen_work.php:Zone.Identifier | Bin 0 -> 25 bytes .../production/slat_work.php:Zone.Identifier | Bin 0 -> 25 bytes .../work_instruction.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/quality/docs.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/quality/record.php:Zone.Identifier | Bin 0 -> 25 bytes .../quality/request.php:Zone.Identifier | Bin 0 -> 25 bytes .../quality/schedule.php:Zone.Identifier | Bin 0 -> 25 bytes .../member_fields.php:Zone.Identifier | Bin 0 -> 25 bytes .../option_groups.php:Zone.Identifier | Bin 0 -> 25 bytes .../monthly_schedule.php:Zone.Identifier | Bin 0 -> 25 bytes .../shipment/status.php:Zone.Identifier | Bin 0 -> 25 bytes .../subscription/list.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant_list.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant_product_list.php:Zone.Identifier | Bin 0 -> 25 bytes .../department_list.php:Zone.Identifier | Bin 0 -> 25 bytes public/tenant/tenant/edit.php:Zone.Identifier | Bin 0 -> 25 bytes public/tenant/tenant/join.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/tenant/option.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/role_add.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/role_delete.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/role_edit.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/role_list.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/subscribe.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/user_edit.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/user_list.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/user_unmap.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/withdraw.php:Zone.Identifier | Bin 0 -> 25 bytes .../tenant/tenant_base.html:Zone.Identifier | Bin 0 -> 25 bytes public/tenant/test.html:Zone.Identifier | Bin 0 -> 25 bytes relationships.txt:Zone.Identifier | Bin 0 -> 25 bytes resources/css/app.css:Zone.Identifier | Bin 0 -> 25 bytes resources/js/app.js:Zone.Identifier | Bin 0 -> 25 bytes resources/js/bootstrap.js:Zone.Identifier | Bin 0 -> 25 bytes resources/markdown/policy.md:Zone.Identifier | Bin 0 -> 25 bytes resources/markdown/terms.md:Zone.Identifier | Bin 0 -> 25 bytes ...pi-token-manager.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../views/api/index.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...confirm-password.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../forgot-password.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../auth/login.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../auth/register.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../reset-password.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...factor-challenge.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../verify-email.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../action-message.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../action-section.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...application-logo.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...application-mark.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...cation-card-logo.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...hentication-card.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../banner.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../button.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../checkbox.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...nfirmation-modal.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...onfirms-password.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../danger-button.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../dialog-modal.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../dropdown-link.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../dropdown.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../form-section.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../input-error.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../input.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../label.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../modal.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../nav-link.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...ponsive-nav-link.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...secondary-button.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../section-border.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../section-title.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../switchable-team.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...alidation-errors.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../welcome.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../views/dashboard.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../team-invitation.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../layouts/app.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../layouts/app.old.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../layouts/footer.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../layouts/guest.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../layouts/left.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../navigation-menu.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../views/policy.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...delete-user-form.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...er-sessions-form.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../profile/show.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...hentication-form.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...te-password-form.blade.php:Zone.Identifier | Bin 0 -> 25 bytes ...information-form.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../views/terms.blade.php:Zone.Identifier | Bin 0 -> 25 bytes .../views/welcome.blade.php:Zone.Identifier | Bin 0 -> 25 bytes routes/api.php:Zone.Identifier | Bin 0 -> 25 bytes routes/console.php:Zone.Identifier | Bin 0 -> 25 bytes routes/web.php:Zone.Identifier | Bin 0 -> 25 bytes .../api-docs/api-docs-v1.json:Zone.Identifier | Bin 0 -> 25 bytes .../api-docs/api-docs.json:Zone.Identifier | Bin 0 -> 25 bytes tailwind.config.js:Zone.Identifier | Bin 0 -> 25 bytes vite.config.js:Zone.Identifier | Bin 0 -> 25 bytes 1533 files changed, 5791 insertions(+) create mode 100644 .dockerignore create mode 100644 .dockerignore:Zone.Identifier create mode 100644 .editorconfig:Zone.Identifier create mode 100644 .env:Zone.Identifier create mode 100644 .gitattributes:Zone.Identifier create mode 100644 .gitignore:Zone.Identifier create mode 100644 CLAUDE.md:Zone.Identifier create mode 100644 CURRENT_WORKS.md:Zone.Identifier create mode 100644 LOGICAL_RELATIONSHIPS.md:Zone.Identifier create mode 100644 README.md:Zone.Identifier create mode 100644 REMOTE_WORK_SETUP.md:Zone.Identifier create mode 100644 app/Console/Commands/CleanupExpiredLinks.php:Zone.Identifier create mode 100644 app/Console/Commands/CleanupTempFiles.php:Zone.Identifier create mode 100644 app/Console/Commands/CleanupTrash.php:Zone.Identifier create mode 100644 app/Console/Commands/FcmPruneInvalidCommand.php:Zone.Identifier create mode 100644 app/Console/Commands/FcmSendCommand.php:Zone.Identifier create mode 100644 app/Console/Commands/FcmTestCommand.php:Zone.Identifier create mode 100644 app/Console/Commands/GenerateSimpleRelationships.php:Zone.Identifier create mode 100644 app/Console/Commands/MakeModelWithRelationships.php:Zone.Identifier create mode 100644 app/Console/Commands/Migrate5130Items.php:Zone.Identifier create mode 100644 app/Console/Commands/PruneAuditLogs.php:Zone.Identifier create mode 100644 app/Console/Commands/RecordStorageUsage.php:Zone.Identifier create mode 100644 app/Console/Commands/SeedMenuPermissions.php:Zone.Identifier create mode 100644 app/Console/Commands/TenantsBootstrap.php:Zone.Identifier create mode 100644 app/Console/Commands/UpdateLogicalRelationships.php:Zone.Identifier create mode 100644 app/Console/Kernel.php:Zone.Identifier create mode 100644 app/Constants/SystemFields.php:Zone.Identifier create mode 100644 app/Enums/EstimateStatus.php:Zone.Identifier create mode 100644 app/Enums/OrderStatus.php:Zone.Identifier create mode 100644 app/Exceptions/DuplicateCodeException.php:Zone.Identifier create mode 100644 app/Exceptions/Handler.php:Zone.Identifier create mode 100644 app/Exports/DailyReportExport.php:Zone.Identifier create mode 100644 app/Exports/ExpenseEstimateExport.php:Zone.Identifier create mode 100644 app/Helpers/ApiResponse.php:Zone.Identifier create mode 100644 app/Helpers/ItemTypeHelper.php:Zone.Identifier create mode 100644 app/Helpers/TenantCodeGenerator.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/Admin/GlobalMenuController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/AccountController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/Admin/FcmController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/AdminController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/AiReportController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ApiController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ApprovalController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ApprovalFormController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ApprovalLineController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/AttendanceController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/BadDebtController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/BankAccountController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/BankTransactionController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/BarobillSettingController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/BillController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/BoardController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/CardController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/CardTransactionController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/CategoryController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/CategoryFieldController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/CategoryLogController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/CategoryTemplateController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ClassificationController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ClientController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ClientGroupController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/CommonController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/CompanyController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ComprehensiveAnalysisController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/Construction/ContractController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/DailyReportController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/DashboardController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/DepartmentController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/DepositController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/Design/AuditLogController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/Design/BomCalculationController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/Design/BomTemplateController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/Design/DesignModelController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/Design/ModelVersionController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/EmployeeController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/EstimateController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ExpectedExpenseController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/FileStorageController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/FolderController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/InternalController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ItemMaster/CustomTabController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ItemMaster/EntityRelationshipController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ItemMaster/ItemBomItemController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ItemMaster/ItemFieldController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ItemMaster/ItemMasterController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ItemMaster/ItemPageController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ItemMaster/ItemSectionController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ItemMaster/SectionTemplateController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ItemMaster/UnitOptionController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ItemsBomController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ItemsController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ItemsFileController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/LeaveController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/LeavePolicyController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/LoanController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/MaterialController.php create mode 100644 app/Http/Controllers/Api/V1/MaterialController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/MenuController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ModelSetController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/NotificationSettingController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/OrderController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/PaymentController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/PayrollController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/PermissionController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/PlanController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/PopupController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/PositionController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/PostController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/PricingController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ProductBomItemController.php create mode 100644 app/Http/Controllers/Api/V1/ProductBomItemController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ProductController.php create mode 100644 app/Http/Controllers/Api/V1/ProductController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/PurchaseController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/PushNotificationController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/QuoteController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ReceivablesController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ReceivingController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/RefreshController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/RegisterController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ReportController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/RoleController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/RolePermissionController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/SalaryController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/SaleController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/ShipmentController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/SiteController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/StockController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/SubscriptionController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/SystemBoardController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/SystemPostController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/TaxInvoiceController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/TenantController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/TenantFieldSettingController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/TenantOptionGroupController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/TenantOptionValueController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/TenantStatFieldController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/TenantUserProfileController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/UserController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/UserInvitationController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/UserRoleController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/VendorLedgerController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/WithdrawalController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/WorkOrderController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/WorkResultController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Api/V1/WorkSettingController.php:Zone.Identifier create mode 100644 app/Http/Controllers/Controller.php:Zone.Identifier create mode 100644 app/Http/Controllers/V1/ProcessController.php:Zone.Identifier create mode 100644 app/Http/Kernel.php:Zone.Identifier create mode 100644 app/Http/Middleware/ApiKeyMiddleware.php:Zone.Identifier create mode 100644 app/Http/Middleware/ApiRateLimiter.php:Zone.Identifier create mode 100644 app/Http/Middleware/CheckPermission.php:Zone.Identifier create mode 100644 app/Http/Middleware/CheckSwaggerAuth.php:Zone.Identifier create mode 100644 app/Http/Middleware/CorsMiddleware.php:Zone.Identifier create mode 100644 app/Http/Middleware/LogApiRequest.php:Zone.Identifier create mode 100644 app/Http/Middleware/PermMapper.php:Zone.Identifier create mode 100644 app/Http/Requests/Account/UpdateAgreementsRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Account/WithdrawRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Admin/FcmHistoryRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Admin/FcmTokenListRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Admin/SendFcmRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Api/V1/FileMoveRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Api/V1/FileUploadRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Api/V1/FolderStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Api/V1/FolderUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Api/V1/RefreshRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Api/V1/ShareLinkRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/FormIndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/FormStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/FormUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/InboxIndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/IndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/LineIndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/LineStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/LineUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/ReferenceIndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/RejectRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/StoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/SubmitRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Approval/UpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Attendance/CheckInRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Attendance/CheckOutRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Attendance/IndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Attendance/MonthlyStatsRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Attendance/StoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Attendance/UpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Audit/AuditLogIndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/BarobillSetting/SaveBarobillSettingRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Boards/BoardStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Boards/BoardUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Boards/CommentStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Boards/PostStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Boards/PostUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Category/CategoryMoveRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Category/CategoryReorderRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Category/CategoryStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Category/CategoryUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/CategoryField/CategoryFieldStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/CategoryField/CategoryFieldUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Client/ClientStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Client/ClientUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Common/PaginateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Construction/ContractStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Construction/ContractUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Design/BomTemplate/CloneRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Design/BomTemplate/DiffRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Design/BomTemplate/ReplaceItemsRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Design/BomTemplate/UpsertRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Design/CalculateBomRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Design/GetEstimateParametersRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Design/Model/StoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Design/Model/UpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Design/ModelVersion/CreateDraftRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Design/SaveCompanyFormulaRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Employee/IndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Employee/StoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Employee/UpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Estimate/CreateEstimateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Estimate/UpdateEstimateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Internal/ExchangeTokenRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Item/ItemBatchDeleteRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Item/ItemFileUploadRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Item/ItemStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Item/ItemUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/CustomTabStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/CustomTabUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/IndependentBomItemStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/IndependentFieldStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/IndependentSectionStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/ItemBomItemStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/ItemBomItemUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/ItemFieldStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/ItemFieldUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/ItemPageStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/ItemPageUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/ItemSectionStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/ItemSectionUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/LinkEntityRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/ReorderRelationshipsRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/ReorderRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/SectionTemplateStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/SectionTemplateUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemMaster/UnitOptionStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/ItemsFileUploadRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Leave/BalanceRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Leave/IndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Leave/RejectRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Leave/StoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Leave/UpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/LeavePolicy/UpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Loan/LoanCalculateInterestRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Loan/LoanIndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Loan/LoanSettleRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Loan/LoanStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Loan/LoanUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Material/MaterialStoreRequest.php create mode 100644 app/Http/Requests/Material/MaterialStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Material/MaterialUpdateRequest.php create mode 100644 app/Http/Requests/Material/MaterialUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/NotificationSetting/BulkUpdateSettingRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/NotificationSetting/UpdateGroupedSettingRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/NotificationSetting/UpdateSettingRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Order/CreateFromQuoteRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Order/CreateProductionOrderRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Order/StoreOrderRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Order/UpdateOrderRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Order/UpdateOrderStatusRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/PositionReorderRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/PositionRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Pricing/PriceByItemsRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Pricing/PriceCostRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Pricing/PriceIndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Pricing/PriceStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Pricing/PriceUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Product/ProductStoreRequest.php create mode 100644 app/Http/Requests/Product/ProductStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Product/ProductUpdateRequest.php create mode 100644 app/Http/Requests/Product/ProductUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Push/RegisterTokenRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Push/UpdateSettingsRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Quote/QuoteBomBulkCalculateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Quote/QuoteBomCalculateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Quote/QuoteBulkDeleteRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Quote/QuoteCalculateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Quote/QuoteIndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Quote/QuoteSendEmailRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Quote/QuoteSendKakaoRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Quote/QuoteStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Quote/QuoteUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/RegisterRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Shipment/ShipmentStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Shipment/ShipmentUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Shipment/ShipmentUpdateStatusRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/TaxInvoice/CancelTaxInvoiceRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/TaxInvoice/CreateTaxInvoiceRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/TaxInvoice/TaxInvoiceListRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/TaxInvoice/TaxInvoiceSummaryRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/TaxInvoice/UpdateTaxInvoiceRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Tenant/TenantLogoUploadRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Tenant/TenantStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/Tenant/TenantUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/TenantStatField/TenantStatFieldStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/TenantStatField/TenantStatFieldUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/User/PasswordChangeRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/User/SwitchTenantRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/User/UserUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/UserInvitation/AcceptInvitationRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/UserInvitation/InviteUserRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/UserInvitation/ListInvitationRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/AiReport/AiReportGenerateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/AiReport/AiReportListRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/BadDebt/StoreBadDebtDocumentRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/BadDebt/StoreBadDebtMemoRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/BadDebt/StoreBadDebtRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/BadDebt/UpdateBadDebtRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/BankAccount/StoreBankAccountRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/BankAccount/UpdateBankAccountRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Bill/StoreBillRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Bill/UpdateBillRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Bill/UpdateBillStatusRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Card/StoreCardRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Card/UpdateCardRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Company/CheckBusinessNumberRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Company/CompanyRequestActionRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Company/CompanyRequestIndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Company/CompanyRequestStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Dashboard/DashboardApprovalsRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Dashboard/DashboardChartsRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Deposit/StoreDepositRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Deposit/UpdateDepositRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/ExpectedExpense/StoreExpectedExpenseRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/ExpectedExpense/UpdateExpectedExpenseRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/ExpectedExpense/UpdateExpectedPaymentDateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Payment/PaymentActionRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Payment/PaymentIndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Payment/PaymentStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Payroll/CalculatePayrollRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Payroll/PayPayrollRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Payroll/StorePayrollRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Payroll/UpdatePayrollRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Payroll/UpdatePayrollSettingRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Plan/PlanIndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Plan/PlanStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Plan/PlanUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Popup/StorePopupRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Popup/UpdatePopupRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Process/StoreProcessRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Process/UpdateProcessRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Purchase/StorePurchaseRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Purchase/UpdatePurchaseRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Receiving/ProcessReceivingRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Receiving/StoreReceivingRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Receiving/UpdateReceivingRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Report/DailyReportRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Report/ExpenseEstimateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Salary/BulkUpdateStatusRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Salary/StoreSalaryRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Salary/UpdateSalaryRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Sale/SendStatementRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Sale/StoreSaleRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Sale/UpdateSaleRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Site/StoreSiteRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Site/UpdateSiteRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Subscription/ExportStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Subscription/SubscriptionCancelRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Subscription/SubscriptionIndexRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Subscription/SubscriptionStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Withdrawal/StoreWithdrawalRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/Withdrawal/UpdateWithdrawalRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/WorkSetting/UpdateAttendanceSettingRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/V1/WorkSetting/UpdateWorkSettingRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/WorkOrder/WorkOrderAssignRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/WorkOrder/WorkOrderIssueRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/WorkOrder/WorkOrderStatusRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/WorkOrder/WorkOrderStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/WorkOrder/WorkOrderUpdateRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/WorkResult/WorkResultStoreRequest.php:Zone.Identifier create mode 100644 app/Http/Requests/WorkResult/WorkResultUpdateRequest.php:Zone.Identifier create mode 100644 app/Models/ApiKey.php:Zone.Identifier create mode 100644 app/Models/ApiRequestLog.php:Zone.Identifier create mode 100644 app/Models/Audit/AuditLog.php:Zone.Identifier create mode 100644 app/Models/BadDebts/BadDebt.php:Zone.Identifier create mode 100644 app/Models/BadDebts/BadDebtDocument.php:Zone.Identifier create mode 100644 app/Models/BadDebts/BadDebtMemo.php:Zone.Identifier create mode 100644 app/Models/Boards/Board.php:Zone.Identifier create mode 100644 app/Models/Boards/BoardComment.php:Zone.Identifier create mode 100644 app/Models/Boards/BoardSetting.php:Zone.Identifier create mode 100644 app/Models/Boards/Post.php:Zone.Identifier create mode 100644 app/Models/Boards/PostCustomFieldValue.php:Zone.Identifier create mode 100644 app/Models/Calculation/CalculationConfig.php:Zone.Identifier create mode 100644 app/Models/CategoryGroup.php:Zone.Identifier create mode 100644 app/Models/Commons/Category.php:Zone.Identifier create mode 100644 app/Models/Commons/CategoryField.php:Zone.Identifier create mode 100644 app/Models/Commons/CategoryLog.php:Zone.Identifier create mode 100644 app/Models/Commons/CategoryTemplate.php:Zone.Identifier create mode 100644 app/Models/Commons/Classification.php:Zone.Identifier create mode 100644 app/Models/Commons/File.php:Zone.Identifier create mode 100644 app/Models/Commons/GlobalMenu.php:Zone.Identifier create mode 100644 app/Models/Commons/Menu.php:Zone.Identifier create mode 100644 app/Models/Commons/Tag.php:Zone.Identifier create mode 100644 app/Models/CompanyRequest.php:Zone.Identifier create mode 100644 app/Models/Construction/Contract.php:Zone.Identifier create mode 100644 app/Models/Design/BomTemplate.php:Zone.Identifier create mode 100644 app/Models/Design/BomTemplateItem.php:Zone.Identifier create mode 100644 app/Models/Design/DesignModel.php:Zone.Identifier create mode 100644 app/Models/Design/ModelVersion.php:Zone.Identifier create mode 100644 app/Models/Estimate/Estimate.php:Zone.Identifier create mode 100644 app/Models/Estimate/EstimateItem.php:Zone.Identifier create mode 100644 app/Models/Estimates/MainRequestEstimate.php:Zone.Identifier create mode 100644 app/Models/FcmSendLog.php:Zone.Identifier create mode 100644 app/Models/FileShareLink.php:Zone.Identifier create mode 100644 app/Models/Folder.php:Zone.Identifier create mode 100644 app/Models/ItemMaster/CustomTab.php:Zone.Identifier create mode 100644 app/Models/ItemMaster/EntityRelationship.php:Zone.Identifier create mode 100644 app/Models/ItemMaster/ItemBomItem.php:Zone.Identifier create mode 100644 app/Models/ItemMaster/ItemField.php:Zone.Identifier create mode 100644 app/Models/ItemMaster/ItemPage.php:Zone.Identifier create mode 100644 app/Models/ItemMaster/ItemSection.php:Zone.Identifier create mode 100644 app/Models/ItemMaster/TabColumn.php:Zone.Identifier create mode 100644 app/Models/ItemMaster/UnitOption.php:Zone.Identifier create mode 100644 app/Models/Items/Item.php:Zone.Identifier create mode 100644 app/Models/Items/ItemDetail.php:Zone.Identifier create mode 100644 app/Models/Items/ItemReceipt.php:Zone.Identifier create mode 100644 app/Models/LoginToken.php:Zone.Identifier create mode 100644 app/Models/MainRequest.php:Zone.Identifier create mode 100644 app/Models/MainRequestFlow.php:Zone.Identifier create mode 100644 app/Models/Materials/Material.php create mode 100644 app/Models/Materials/Material.php:Zone.Identifier create mode 100644 app/Models/Materials/MaterialInspection.php create mode 100644 app/Models/Materials/MaterialInspection.php:Zone.Identifier create mode 100644 app/Models/Materials/MaterialInspectionItem.php create mode 100644 app/Models/Materials/MaterialInspectionItem.php:Zone.Identifier create mode 100644 app/Models/Materials/MaterialReceipt.php create mode 100644 app/Models/Materials/MaterialReceipt.php:Zone.Identifier create mode 100644 app/Models/Members/User.php:Zone.Identifier create mode 100644 app/Models/Members/UserMenuPermission.php:Zone.Identifier create mode 100644 app/Models/Members/UserRole.php:Zone.Identifier create mode 100644 app/Models/Members/UserTenant.php:Zone.Identifier create mode 100644 app/Models/NotificationSetting.php:Zone.Identifier create mode 100644 app/Models/NotificationSettingGroup.php:Zone.Identifier create mode 100644 app/Models/NotificationSettingGroupItem.php:Zone.Identifier create mode 100644 app/Models/NotificationSettingGroupState.php:Zone.Identifier create mode 100644 app/Models/Orders/Client.php:Zone.Identifier create mode 100644 app/Models/Orders/ClientGroup.php:Zone.Identifier create mode 100644 app/Models/Orders/Order.php:Zone.Identifier create mode 100644 app/Models/Orders/OrderHistory.php:Zone.Identifier create mode 100644 app/Models/Orders/OrderItem.php:Zone.Identifier create mode 100644 app/Models/Orders/OrderItemComponent.php:Zone.Identifier create mode 100644 app/Models/Orders/OrderVersion.php:Zone.Identifier create mode 100644 app/Models/Permissions/Permission.php:Zone.Identifier create mode 100644 app/Models/Permissions/PermissionOverride.php:Zone.Identifier create mode 100644 app/Models/Permissions/Role.php:Zone.Identifier create mode 100644 app/Models/Permissions/RoleMenuPermission.php:Zone.Identifier create mode 100644 app/Models/Popups/Popup.php:Zone.Identifier create mode 100644 app/Models/Process.php:Zone.Identifier create mode 100644 app/Models/ProcessClassificationRule.php:Zone.Identifier create mode 100644 app/Models/ProcessItem.php:Zone.Identifier create mode 100644 app/Models/Production/WorkOrder.php:Zone.Identifier create mode 100644 app/Models/Production/WorkOrderAssignee.php:Zone.Identifier create mode 100644 app/Models/Production/WorkOrderBendingDetail.php:Zone.Identifier create mode 100644 app/Models/Production/WorkOrderIssue.php:Zone.Identifier create mode 100644 app/Models/Production/WorkOrderItem.php:Zone.Identifier create mode 100644 app/Models/Production/WorkResult.php:Zone.Identifier create mode 100644 app/Models/Products/CommonCode.php create mode 100644 app/Models/Products/CommonCode.php:Zone.Identifier create mode 100644 app/Models/Products/Part.php create mode 100644 app/Models/Products/Part.php:Zone.Identifier create mode 100644 app/Models/Products/Price.php:Zone.Identifier create mode 100644 app/Models/Products/PriceRevision.php:Zone.Identifier create mode 100644 app/Models/Products/Product.php create mode 100644 app/Models/Products/Product.php:Zone.Identifier create mode 100644 app/Models/Products/ProductComponent.php create mode 100644 app/Models/Products/ProductComponent.php:Zone.Identifier create mode 100644 app/Models/PushDeviceToken.php:Zone.Identifier create mode 100644 app/Models/PushNotificationSetting.php:Zone.Identifier create mode 100644 app/Models/Qualitys/Inspection.php:Zone.Identifier create mode 100644 app/Models/Qualitys/Lot.php:Zone.Identifier create mode 100644 app/Models/Qualitys/LotSale.php:Zone.Identifier create mode 100644 app/Models/Quote/Quote.php:Zone.Identifier create mode 100644 app/Models/Quote/QuoteFormula.php:Zone.Identifier create mode 100644 app/Models/Quote/QuoteFormulaCategory.php:Zone.Identifier create mode 100644 app/Models/Quote/QuoteFormulaItem.php:Zone.Identifier create mode 100644 app/Models/Quote/QuoteFormulaMapping.php:Zone.Identifier create mode 100644 app/Models/Quote/QuoteFormulaRange.php:Zone.Identifier create mode 100644 app/Models/Quote/QuoteItem.php:Zone.Identifier create mode 100644 app/Models/Quote/QuoteRevision.php:Zone.Identifier create mode 100644 app/Models/Scopes/TenantScope.php:Zone.Identifier create mode 100644 app/Models/SiteAdmin.php:Zone.Identifier create mode 100644 app/Models/SystemFieldDefinition.php:Zone.Identifier create mode 100644 app/Models/Tenants/AiReport.php:Zone.Identifier create mode 100644 app/Models/Tenants/Approval.php:Zone.Identifier create mode 100644 app/Models/Tenants/ApprovalForm.php:Zone.Identifier create mode 100644 app/Models/Tenants/ApprovalLine.php:Zone.Identifier create mode 100644 app/Models/Tenants/ApprovalStep.php:Zone.Identifier create mode 100644 app/Models/Tenants/Attendance.php:Zone.Identifier create mode 100644 app/Models/Tenants/AttendanceSetting.php:Zone.Identifier create mode 100644 app/Models/Tenants/BankAccount.php:Zone.Identifier create mode 100644 app/Models/Tenants/BarobillSetting.php:Zone.Identifier create mode 100644 app/Models/Tenants/Bill.php:Zone.Identifier create mode 100644 app/Models/Tenants/BillInstallment.php:Zone.Identifier create mode 100644 app/Models/Tenants/Card.php:Zone.Identifier create mode 100644 app/Models/Tenants/DataExport.php:Zone.Identifier create mode 100644 app/Models/Tenants/Department.php:Zone.Identifier create mode 100644 app/Models/Tenants/Deposit.php:Zone.Identifier create mode 100644 app/Models/Tenants/ExpectedExpense.php:Zone.Identifier create mode 100644 app/Models/Tenants/Leave.php:Zone.Identifier create mode 100644 app/Models/Tenants/LeaveBalance.php:Zone.Identifier create mode 100644 app/Models/Tenants/LeaveGrant.php:Zone.Identifier create mode 100644 app/Models/Tenants/LeavePolicy.php:Zone.Identifier create mode 100644 app/Models/Tenants/Loan.php:Zone.Identifier create mode 100644 app/Models/Tenants/Payment.php:Zone.Identifier create mode 100644 app/Models/Tenants/Payroll.php:Zone.Identifier create mode 100644 app/Models/Tenants/PayrollSetting.php:Zone.Identifier create mode 100644 app/Models/Tenants/Pivots/DepartmentUser.php:Zone.Identifier create mode 100644 app/Models/Tenants/Plan.php:Zone.Identifier create mode 100644 app/Models/Tenants/Position.php:Zone.Identifier create mode 100644 app/Models/Tenants/Purchase.php:Zone.Identifier create mode 100644 app/Models/Tenants/Receiving.php:Zone.Identifier create mode 100644 app/Models/Tenants/Salary.php:Zone.Identifier create mode 100644 app/Models/Tenants/Sale.php:Zone.Identifier create mode 100644 app/Models/Tenants/SettingFieldDef.php:Zone.Identifier create mode 100644 app/Models/Tenants/Shipment.php:Zone.Identifier create mode 100644 app/Models/Tenants/ShipmentItem.php:Zone.Identifier create mode 100644 app/Models/Tenants/Site.php:Zone.Identifier create mode 100644 app/Models/Tenants/Stock.php:Zone.Identifier create mode 100644 app/Models/Tenants/StockLot.php:Zone.Identifier create mode 100644 app/Models/Tenants/Subscription.php:Zone.Identifier create mode 100644 app/Models/Tenants/TaxInvoice.php:Zone.Identifier create mode 100644 app/Models/Tenants/Tenant.php:Zone.Identifier create mode 100644 app/Models/Tenants/TenantFieldSetting.php:Zone.Identifier create mode 100644 app/Models/Tenants/TenantOptionGroup.php:Zone.Identifier create mode 100644 app/Models/Tenants/TenantOptionValue.php:Zone.Identifier create mode 100644 app/Models/Tenants/TenantStatField.php:Zone.Identifier create mode 100644 app/Models/Tenants/TenantUserProfile.php:Zone.Identifier create mode 100644 app/Models/Tenants/Withdrawal.php:Zone.Identifier create mode 100644 app/Models/Tenants/WorkSetting.php:Zone.Identifier create mode 100644 app/Models/UserInvitation.php:Zone.Identifier create mode 100644 app/Observers/MenuObserver.php:Zone.Identifier create mode 100644 app/Observers/TenantObserver.php:Zone.Identifier create mode 100644 app/Providers/AppServiceProvider.php:Zone.Identifier create mode 100644 app/Providers/MigrationServiceProvider.php:Zone.Identifier create mode 100644 app/Repositories/MainRequestRepository.php:Zone.Identifier create mode 100644 app/Services/AccountService.php:Zone.Identifier create mode 100644 app/Services/AdminFcmService.php:Zone.Identifier create mode 100644 app/Services/AdminPermissionService.php:Zone.Identifier create mode 100644 app/Services/AdminService.php:Zone.Identifier create mode 100644 app/Services/AiReportService.php:Zone.Identifier create mode 100644 app/Services/ApprovalService.php:Zone.Identifier create mode 100644 app/Services/AttendanceService.php:Zone.Identifier create mode 100644 app/Services/Audit/AuditLogService.php:Zone.Identifier create mode 100644 app/Services/Audit/AuditLogger.php:Zone.Identifier create mode 100644 app/Services/AuthService.php:Zone.Identifier create mode 100644 app/Services/Authz/AccessService.php:Zone.Identifier create mode 100644 app/Services/Authz/RolePermissionService.php:Zone.Identifier create mode 100644 app/Services/Authz/RoleService.php:Zone.Identifier create mode 100644 app/Services/Authz/UserRoleService.php:Zone.Identifier create mode 100644 app/Services/BadDebtService.php:Zone.Identifier create mode 100644 app/Services/BankAccountService.php:Zone.Identifier create mode 100644 app/Services/BankTransactionService.php:Zone.Identifier create mode 100644 app/Services/BarobillService.php:Zone.Identifier create mode 100644 app/Services/BillService.php:Zone.Identifier create mode 100644 app/Services/Boards/BoardService.php:Zone.Identifier create mode 100644 app/Services/Boards/PostService.php:Zone.Identifier create mode 100644 app/Services/Calculation/CalculationEngine.php:Zone.Identifier create mode 100644 app/Services/Calculation/FormulaParser.php:Zone.Identifier create mode 100644 app/Services/Calculation/ParameterValidator.php:Zone.Identifier create mode 100644 app/Services/CardService.php:Zone.Identifier create mode 100644 app/Services/CardTransactionService.php:Zone.Identifier create mode 100644 app/Services/CategoryFieldService.php:Zone.Identifier create mode 100644 app/Services/CategoryLogService.php:Zone.Identifier create mode 100644 app/Services/CategoryService.php:Zone.Identifier create mode 100644 app/Services/CategoryTemplateService.php:Zone.Identifier create mode 100644 app/Services/ClassificationService.php:Zone.Identifier create mode 100644 app/Services/ClientGroupService.php:Zone.Identifier create mode 100644 app/Services/ClientService.php:Zone.Identifier create mode 100644 app/Services/CompanyService.php:Zone.Identifier create mode 100644 app/Services/ComprehensiveAnalysisService.php:Zone.Identifier create mode 100644 app/Services/Construction/ContractService.php:Zone.Identifier create mode 100644 app/Services/DailyReportService.php:Zone.Identifier create mode 100644 app/Services/DashboardService.php:Zone.Identifier create mode 100644 app/Services/DepartmentService.php:Zone.Identifier create mode 100644 app/Services/DepositService.php:Zone.Identifier create mode 100644 app/Services/Design/BomCalculationService.php:Zone.Identifier create mode 100644 app/Services/Design/BomTemplateService.php:Zone.Identifier create mode 100644 app/Services/Design/ModelService.php:Zone.Identifier create mode 100644 app/Services/Design/ModelVersionService.php:Zone.Identifier create mode 100644 app/Services/EmployeeService.php:Zone.Identifier create mode 100644 app/Services/Estimate/EstimateService.php:Zone.Identifier create mode 100644 app/Services/EstimateService.php:Zone.Identifier create mode 100644 app/Services/ExpectedExpenseService.php:Zone.Identifier create mode 100644 app/Services/Fcm/FcmBatchResult.php:Zone.Identifier create mode 100644 app/Services/Fcm/FcmException.php:Zone.Identifier create mode 100644 app/Services/Fcm/FcmResponse.php:Zone.Identifier create mode 100644 app/Services/Fcm/FcmSender.php:Zone.Identifier create mode 100644 app/Services/FileService.php:Zone.Identifier create mode 100644 app/Services/FileStorageService.php:Zone.Identifier create mode 100644 app/Services/FolderService.php:Zone.Identifier create mode 100644 app/Services/GlobalMenuService.php:Zone.Identifier create mode 100644 app/Services/InternalTokenService.php:Zone.Identifier create mode 100644 app/Services/ItemMaster/CustomTabService.php:Zone.Identifier create mode 100644 app/Services/ItemMaster/EntityRelationshipService.php:Zone.Identifier create mode 100644 app/Services/ItemMaster/ItemBomItemService.php:Zone.Identifier create mode 100644 app/Services/ItemMaster/ItemDataService.php:Zone.Identifier create mode 100644 app/Services/ItemMaster/ItemFieldService.php:Zone.Identifier create mode 100644 app/Services/ItemMaster/ItemMasterService.php:Zone.Identifier create mode 100644 app/Services/ItemMaster/ItemPageService.php:Zone.Identifier create mode 100644 app/Services/ItemMaster/ItemSectionService.php:Zone.Identifier create mode 100644 app/Services/ItemMaster/SectionTemplateService.php:Zone.Identifier create mode 100644 app/Services/ItemMaster/UnitOptionService.php:Zone.Identifier create mode 100644 app/Services/ItemService.php:Zone.Identifier create mode 100644 app/Services/ItemsService.php create mode 100644 app/Services/ItemsService.php:Zone.Identifier create mode 100644 app/Services/LeavePolicyService.php:Zone.Identifier create mode 100644 app/Services/LeaveService.php:Zone.Identifier create mode 100644 app/Services/LoanService.php:Zone.Identifier create mode 100644 app/Services/MaterialService.php create mode 100644 app/Services/MaterialService.php:Zone.Identifier create mode 100644 app/Services/MemberService.php:Zone.Identifier create mode 100644 app/Services/MenuBootstrapService.php:Zone.Identifier create mode 100644 app/Services/MenuService.php:Zone.Identifier create mode 100644 app/Services/MenuSyncService.php:Zone.Identifier create mode 100644 app/Services/ModelSet/ModelSetService.php:Zone.Identifier create mode 100644 app/Services/NotificationSettingService.php:Zone.Identifier create mode 100644 app/Services/OrderService.php:Zone.Identifier create mode 100644 app/Services/PaymentService.php:Zone.Identifier create mode 100644 app/Services/PayrollService.php:Zone.Identifier create mode 100644 app/Services/PermissionService.php:Zone.Identifier create mode 100644 app/Services/PlanService.php:Zone.Identifier create mode 100644 app/Services/PopupService.php:Zone.Identifier create mode 100644 app/Services/PositionService.php:Zone.Identifier create mode 100644 app/Services/Pricing/PricingService.php:Zone.Identifier create mode 100644 app/Services/PricingService.php:Zone.Identifier create mode 100644 app/Services/ProcessService.php:Zone.Identifier create mode 100644 app/Services/ProductBomService.php create mode 100644 app/Services/ProductBomService.php:Zone.Identifier create mode 100644 app/Services/ProductService.php create mode 100644 app/Services/ProductService.php:Zone.Identifier create mode 100644 app/Services/Products/ProductComponentResolver.php create mode 100644 app/Services/Products/ProductComponentResolver.php:Zone.Identifier create mode 100644 app/Services/PurchaseService.php:Zone.Identifier create mode 100644 app/Services/PushNotificationService.php:Zone.Identifier create mode 100644 app/Services/Quote/FormulaEvaluatorService.php:Zone.Identifier create mode 100644 app/Services/Quote/QuoteCalculationService.php:Zone.Identifier create mode 100644 app/Services/Quote/QuoteDocumentService.php:Zone.Identifier create mode 100644 app/Services/Quote/QuoteNumberService.php:Zone.Identifier create mode 100644 app/Services/Quote/QuoteService.php:Zone.Identifier create mode 100644 app/Services/ReceivablesService.php:Zone.Identifier create mode 100644 app/Services/ReceivingService.php:Zone.Identifier create mode 100644 app/Services/RegisterService.php:Zone.Identifier create mode 100644 app/Services/ReportService.php:Zone.Identifier create mode 100644 app/Services/SalaryService.php:Zone.Identifier create mode 100644 app/Services/SaleService.php:Zone.Identifier create mode 100644 app/Services/Service.php:Zone.Identifier create mode 100644 app/Services/ShipmentService.php:Zone.Identifier create mode 100644 app/Services/SiteService.php:Zone.Identifier create mode 100644 app/Services/StockService.php:Zone.Identifier create mode 100644 app/Services/SubscriptionService.php:Zone.Identifier create mode 100644 app/Services/TaxInvoiceService.php:Zone.Identifier create mode 100644 app/Services/TenantBootstrap/Contracts/TenantBootstrapStep.php:Zone.Identifier create mode 100644 app/Services/TenantBootstrap/RecipeRegistry.php:Zone.Identifier create mode 100644 app/Services/TenantBootstrap/Steps/CapabilityProfilesStep.php:Zone.Identifier create mode 100644 app/Services/TenantBootstrap/Steps/CategoriesStep.php:Zone.Identifier create mode 100644 app/Services/TenantBootstrap/Steps/MenusStep.php:Zone.Identifier create mode 100644 app/Services/TenantBootstrap/Steps/SettingsStep.php:Zone.Identifier create mode 100644 app/Services/TenantBootstrap/Support/TenantBootstrapLogger.php:Zone.Identifier create mode 100644 app/Services/TenantBootstrapper.php:Zone.Identifier create mode 100644 app/Services/TenantFieldSettingService.php:Zone.Identifier create mode 100644 app/Services/TenantOptionGroupService.php:Zone.Identifier create mode 100644 app/Services/TenantOptionValueService.php:Zone.Identifier create mode 100644 app/Services/TenantService.php:Zone.Identifier create mode 100644 app/Services/TenantStatFieldService.php:Zone.Identifier create mode 100644 app/Services/TenantUserProfileService.php:Zone.Identifier create mode 100644 app/Services/UserInvitationService.php:Zone.Identifier create mode 100644 app/Services/VendorLedgerService.php:Zone.Identifier create mode 100644 app/Services/WithdrawalService.php:Zone.Identifier create mode 100644 app/Services/WorkOrderService.php:Zone.Identifier create mode 100644 app/Services/WorkResultService.php:Zone.Identifier create mode 100644 app/Services/WorkSettingService.php:Zone.Identifier create mode 100644 app/Support/Validation/BomItemRules.php:Zone.Identifier create mode 100644 app/Swagger/v1/AccountApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/AdminApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/AdminFcmApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/AdminGlobalMenuApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/AiReportApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ApprovalApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ApprovalFormApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ApprovalLineApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/AttendanceApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/AuditLogApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/AuthApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/BadDebtApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/BankAccountApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/BankTransactionApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/BarobillSettingApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/BillApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/BoardApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/BomCalculationApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/CardApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/CardTransactionApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/CategoryApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/CategoryExtras.php:Zone.Identifier create mode 100644 app/Swagger/v1/ClassificationApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ClientApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ClientGroupApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/CommonApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/CommonComponents.php:Zone.Identifier create mode 100644 app/Swagger/v1/CompanyApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ComprehensiveAnalysisApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ContractApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/DailyReportApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/DashboardApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/DepartmentApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/DepositApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/DesignBomTemplateExtras.php:Zone.Identifier create mode 100644 app/Swagger/v1/DesignModelApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/EmployeeApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/EntityRelationshipApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/EstimateApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ExpectedExpenseApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/FieldProfileApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/FileApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/FolderApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/InternalApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ItemMasterApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ItemsApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ItemsBomApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ItemsFileApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/LeaveApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/LeavePolicyApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/LoanApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/MaterialApi.php create mode 100644 app/Swagger/v1/MaterialApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/MenuApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ModelApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ModelSetApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/NotificationSettingApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/OrderApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/PaymentApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/PayrollApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/PermissionApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/PlanApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/PopupApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/PositionApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/PostApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/PricingApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ProcessApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ProductApi.php create mode 100644 app/Swagger/v1/ProductApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ProductExtraSchemas.php create mode 100644 app/Swagger/v1/ProductExtraSchemas.php:Zone.Identifier create mode 100644 app/Swagger/v1/PurchaseApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/PushApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/QuoteApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ReceivablesApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ReceivingApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/RefreshApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/RegisterApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ReportApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/RoleApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/RolePermissionApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/SAMInfo.php:Zone.Identifier create mode 100644 app/Swagger/v1/SaleApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/ShipmentApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/SiteApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/StockApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/SubscriptionApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/SystemBoardApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/TaxInvoiceApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/TenantApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/TenantFieldSettingApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/TenantStatFieldApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/UserApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/UserInvitationApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/UserRoleApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/VendorLedgerApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/WithdrawalApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/WorkOrderApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/WorkResultApi.php:Zone.Identifier create mode 100644 app/Swagger/v1/WorkSettingApi.php:Zone.Identifier create mode 100644 app/Traits/BelongsToTenant.php:Zone.Identifier create mode 100644 app/Traits/LockCheckTrait.php:Zone.Identifier create mode 100644 app/Traits/ModelTrait.php:Zone.Identifier create mode 100644 app/Traits/UppercaseAttributes.php:Zone.Identifier create mode 100644 app/View/Components/AppLayout.php:Zone.Identifier create mode 100644 app/View/Components/GuestLayout.php:Zone.Identifier create mode 100644 artisan:Zone.Identifier create mode 100644 bootstrap/app.php:Zone.Identifier create mode 100644 bootstrap/providers.php:Zone.Identifier create mode 100644 composer.json:Zone.Identifier create mode 100644 composer.lock:Zone.Identifier create mode 100644 config/app.php:Zone.Identifier create mode 100644 config/audit.php:Zone.Identifier create mode 100644 config/auth.php:Zone.Identifier create mode 100644 config/authz.php:Zone.Identifier create mode 100644 config/cache.php:Zone.Identifier create mode 100644 config/cors.php:Zone.Identifier create mode 100644 config/custom.php:Zone.Identifier create mode 100644 config/database.php:Zone.Identifier create mode 100644 config/er-diagram-generator.php:Zone.Identifier create mode 100644 config/fcm.php:Zone.Identifier create mode 100644 config/filesystems.php:Zone.Identifier create mode 100644 config/l5-swagger.php:Zone.Identifier create mode 100644 config/livewire.php:Zone.Identifier create mode 100644 config/logging.php:Zone.Identifier create mode 100644 config/mail.php:Zone.Identifier create mode 100644 config/permission.php:Zone.Identifier create mode 100644 config/products.php:Zone.Identifier create mode 100644 config/queue.php:Zone.Identifier create mode 100644 config/sanctum.php:Zone.Identifier create mode 100644 config/services.php:Zone.Identifier create mode 100644 config/session.php:Zone.Identifier create mode 100644 database/.DS_Store:Zone.Identifier create mode 100644 database/.gitignore:Zone.Identifier create mode 100644 database/factories/UserFactory.php:Zone.Identifier create mode 100644 database/migrations/2025_01_08_100000_add_tenant_id_to_work_order_sub_tables.php create mode 100644 database/migrations/2025_01_08_100000_add_tenant_id_to_work_order_sub_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_01_09_100000_create_work_order_assignees_table.php create mode 100644 database/migrations/2025_01_09_100000_create_work_order_assignees_table.php:Zone.Identifier create mode 100644 database/migrations/2025_08_15_000000_create_authz_structures.php:Zone.Identifier create mode 100644 database/migrations/2025_08_15_000100_update_spatie_permission_for_teams_and_guard.php:Zone.Identifier create mode 100644 database/migrations/2025_08_15_000200_drop_slug_from_menus_table.php:Zone.Identifier create mode 100644 database/migrations/2025_08_19_000001_add_colomn_parent_id_departments.php:Zone.Identifier create mode 100644 database/migrations/2025_08_21_000000_unify_permissions_to_spatie_and_overrides.php:Zone.Identifier create mode 100644 database/migrations/2025_08_21_000100_create_materials_table.php:Zone.Identifier create mode 100644 database/migrations/2025_08_22_001500_finalize_categories_products_profile_and_bom.php:Zone.Identifier create mode 100644 database/migrations/2025_08_22_001600_create_tenant_bootstrap_runs_table.php:Zone.Identifier create mode 100644 database/migrations/2025_08_22_002000_create_classifications_table.php:Zone.Identifier create mode 100644 database/migrations/2025_08_25_153000_update_product_components_add_ref_type_and_material_id.php:Zone.Identifier create mode 100644 database/migrations/2025_08_26_222920_add_unit_to_products_table.php:Zone.Identifier create mode 100644 database/migrations/2025_08_28_000100_alter_product_components_unify_ref_columns.php:Zone.Identifier create mode 100644 database/migrations/2025_09_05_000001_create_models_table.php:Zone.Identifier create mode 100644 database/migrations/2025_09_05_000002_create_model_versions_table.php:Zone.Identifier create mode 100644 database/migrations/2025_09_05_000003_create_bom_templates_table.php:Zone.Identifier create mode 100644 database/migrations/2025_09_05_000004_create_bom_template_items_table.php:Zone.Identifier create mode 100644 database/migrations/2025_09_10_000002_add_indexes_to_model_versions_table.php:Zone.Identifier create mode 100644 database/migrations/2025_09_11_000100_create_audit_logs_table.php:Zone.Identifier create mode 100644 database/migrations/2025_09_22_215127_add_calculation_fields_to_bom_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_09_22_215217_create_calculation_configs_table.php:Zone.Identifier create mode 100644 database/migrations/2025_09_24_000002_create_dynamic_estimate_fields.php:Zone.Identifier create mode 100644 database/migrations/2025_09_24_000003_create_estimates_table.php:Zone.Identifier create mode 100644 database/migrations/2025_09_24_214146_remove_non_critical_foreign_keys_phase1.php:Zone.Identifier create mode 100644 database/migrations/2025_09_24_214200_remove_estimate_foreign_keys_phase2.php:Zone.Identifier create mode 100644 database/migrations/2025_09_24_214300_remove_material_foreign_key_phase3.php:Zone.Identifier create mode 100644 database/migrations/2025_10_13_213549_create_client_groups_table.php:Zone.Identifier create mode 100644 database/migrations/2025_10_13_213556_add_client_group_id_to_clients_table.php:Zone.Identifier create mode 100644 database/migrations/2025_10_13_213602_add_client_group_id_to_price_histories_table.php:Zone.Identifier create mode 100644 database/migrations/2025_10_14_135811_add_role_and_is_active_to_users_table.php:Zone.Identifier create mode 100644 database/migrations/2025_10_14_135811_create_prospects_table.php:Zone.Identifier create mode 100644 database/migrations/2025_10_14_135812_create_demo_links_table.php:Zone.Identifier create mode 100644 database/migrations/2025_10_14_145318_add_is_super_admin_to_users_table.php:Zone.Identifier create mode 100644 database/migrations/2025_10_14_204237_change_role_column_to_varchar_in_users_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_10_190208_enhance_files_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_10_190257_create_folders_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_10_190355_add_storage_columns_to_tenants.php:Zone.Identifier create mode 100644 database/migrations/2025_11_10_190355_create_file_deletion_logs_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_10_190355_create_file_share_links_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_10_190355_create_storage_usage_history_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_11_112258_add_material_type_to_materials_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_11_225245_create_archived_records_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_11_12_160656_add_performance_indexes_to_menus_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_14_000001_add_hybrid_fields_to_products_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_14_000002_add_attributes_to_product_components_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_14_000003_create_tenant_stat_fields_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_17_125437_add_file_fields_to_products_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_17_145307_add_is_active_to_products_and_materials_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_11_20_100000_create_unit_options_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_20_100001_create_section_templates_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_20_100002_create_item_master_fields_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_20_100003_create_item_pages_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_20_100004_create_item_sections_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_20_100005_create_item_fields_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_20_100006_create_item_bom_items_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_20_100007_create_custom_tabs_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_20_100008_create_tab_columns_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_24_192518_add_audit_columns_to_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_11_24_192518_add_deleted_by_to_soft_delete_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_11_26_100001_convert_item_tables_to_independent_entities.php:Zone.Identifier create mode 100644 database/migrations/2025_11_26_100002_create_entity_relationships_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_26_100003_migrate_existing_relationships_to_entity_relationships.php:Zone.Identifier create mode 100644 database/migrations/2025_11_26_170358_make_page_id_nullable_in_item_sections_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_26_200001_add_is_template_to_item_sections_and_migrate_data.php:Zone.Identifier create mode 100644 database/migrations/2025_11_26_230132_add_master_field_columns_to_item_fields_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_26_230719_add_batch_fields_to_archived_records_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_27_090523_drop_item_master_fields_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_27_092448_remove_fk_columns_from_item_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_11_27_100000_create_admin_api_flow_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_11_27_151643_add_is_locked_to_entity_relationships_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_27_165658_add_tenant_type_to_tenants_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_27_205429_add_system_fields_to_boards_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_27_220000_create_admin_pm_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_11_28_171952_add_field_key_and_lock_columns_to_item_fields_table.php:Zone.Identifier create mode 100644 database/migrations/2025_11_28_174039_add_is_urgent_to_pm_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_11_30_144617_modify_archived_records_record_type_to_varchar.php:Zone.Identifier create mode 100644 database/migrations/2025_12_01_002115_add_tenant_id_to_archived_records.php:Zone.Identifier create mode 100644 database/migrations/2025_12_01_111252_create_admin_pm_daily_logs_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_12_01_232808_add_must_change_password_to_users_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_02_100000_add_global_menu_link_columns_to_menus_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_02_150000_create_global_menus_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_02_155241_add_schedule_fields_to_admin_pm_issues_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_02_163035_alter_products_table_set_category_id_default.php:Zone.Identifier create mode 100644 database/migrations/2025_12_02_163431_alter_products_table_category_id_nullable.php:Zone.Identifier create mode 100644 database/migrations/2025_12_02_183031_add_team_assignee_client_fields_to_admin_pm_issues_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_02_232143_alter_failed_step_column_in_admin_api_flow_runs_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_04_133410_create_quote_formula_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_12_04_142000_add_api_logs_to_admin_api_flow_runs_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_04_145912_add_business_fields_to_clients_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_04_164542_create_quotes_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_04_205603_add_extended_fields_to_clients_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_05_094957_add_is_active_column_to_item_fields_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_08_154633_create_prices_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_08_154634_create_price_revisions_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_08_154635_migrate_price_histories_to_prices.php:Zone.Identifier create mode 100644 database/migrations/2025_12_08_154636_drop_price_histories_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_08_191113_add_source_table_to_item_pages_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_08_191114_add_source_mapping_columns_to_item_fields_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_08_200913_convert_clients_is_active_to_boolean.php:Zone.Identifier create mode 100644 database/migrations/2025_12_09_084138_add_employee_status_to_tenant_user_profiles_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_09_084231_create_attendances_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_09_110130_add_remarks_to_attendances_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_10_211539_add_options_column_to_products_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_11_121758_modify_item_fields_unique_constraint.php:Zone.Identifier create mode 100644 database/migrations/2025_12_11_204116_add_bom_column_to_products_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_11_220000_create_items_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_11_220100_create_item_id_mappings_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_11_220200_migrate_products_materials_to_items.php:Zone.Identifier create mode 100644 database/migrations/2025_12_12_100000_rollback_items_migration.php:Zone.Identifier create mode 100644 database/migrations/2025_12_12_182336_alter_files_table_add_field_key_and_change_file_type.php:Zone.Identifier create mode 100644 database/migrations/2025_12_13_152423_normalize_item_types_before_unification.php:Zone.Identifier create mode 100644 database/migrations/2025_12_13_152507_create_items_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_13_152553_create_item_details_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_13_152631_migrate_products_materials_to_items.php:Zone.Identifier create mode 100644 database/migrations/2025_12_13_153116_update_item_pages_source_table_to_items.php:Zone.Identifier create mode 100644 database/migrations/2025_12_13_153544_update_reference_tables_to_items.php:Zone.Identifier create mode 100644 database/migrations/2025_12_13_160000_update_bom_child_item_ids_to_new_item_ids.php:Zone.Identifier create mode 100644 database/migrations/2025_12_14_001312_drop_products_and_materials_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_12_14_012415_drop_legacy_product_material_id_columns.php:Zone.Identifier create mode 100644 database/migrations/2025_12_15_143850_add_item_group_to_common_codes.php:Zone.Identifier create mode 100644 database/migrations/2025_12_15_144707_create_api_request_logs_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_15_160033_add_group_id_to_api_request_logs_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_16_000001_add_options_to_menus_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_16_012109_create_biz_cert_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_16_144658_create_admin_meeting_logs_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_16_180058_create_system_field_definitions_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_100000_create_leaves_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_100001_create_approval_forms_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_100001_create_leave_balances_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_100001_create_sales_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_100002_create_approval_lines_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_100002_create_purchases_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_100003_create_approvals_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_100004_create_approval_steps_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_110000_create_work_settings_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_110001_create_attendance_settings_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_110002_create_sites_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_120000_create_cards_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_120001_create_bank_accounts_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_130000_create_deposits_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_130001_create_withdrawals_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_200001_create_admin_api_bookmarks_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_200002_create_admin_api_templates_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_200003_create_admin_api_histories_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_17_200004_create_admin_api_environments_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_18_100001_create_payrolls_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_18_100001_create_push_device_tokens_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_18_100002_create_payroll_settings_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_18_100002_create_push_notification_settings_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_18_120001_create_loans_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_18_132727_create_ai_reports_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_18_170000_create_admin_api_deprecations_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_18_200001_create_barobill_settings_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_18_200002_create_tax_invoices_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_18_223350_add_last_error_to_push_device_tokens.php:Zone.Identifier create mode 100644 database/migrations/2025_12_19_100000_create_fcm_send_logs_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_19_100001_create_user_invitations_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_19_100002_create_notification_settings_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_19_160001_create_bad_debts_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_19_160002_create_bad_debt_documents_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_19_160003_create_bad_debt_memos_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_19_164035_create_data_exports_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_19_170001_create_popups_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_20_122054_add_source_table_index_to_system_field_definitions_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_20_132721_create_login_tokens_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_20_222346_add_client_and_quote_codes_to_common_codes.php:Zone.Identifier create mode 100644 database/migrations/2025_12_21_160215_convert_clients_enum_to_varchar.php:Zone.Identifier create mode 100644 database/migrations/2025_12_21_165524_update_prices_item_type_code_to_actual_item_type.php:Zone.Identifier create mode 100644 database/migrations/2025_12_21_171944_add_is_material_to_common_codes_item_type.php:Zone.Identifier create mode 100644 database/migrations/2025_12_22_100001_create_company_requests_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_22_171959_create_notification_setting_groups_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_12_22_222428_alter_payments_paid_at_nullable.php:Zone.Identifier create mode 100644 database/migrations/2025_12_22_222722_add_cancel_columns_to_subscriptions_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_23_100000_create_bills_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_23_222356_remove_bad_debt_columns_from_clients_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_24_151437_add_invoice_flags_to_sales_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_24_160000_add_tax_invoice_received_to_purchases_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_24_193042_create_leave_grants_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_25_004032_create_salaries_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_000001_create_expected_expenses_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_100000_create_work_orders_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_100001_create_leave_policies_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_100100_create_work_order_items_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_100200_create_work_order_bending_details_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_100300_create_work_order_issues_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_131150_create_receivings_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_132806_create_stocks_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_132842_create_stock_lots_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_133933_add_card_fields_to_withdrawals_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_150334_create_work_results_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_150604_create_shipments_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_150605_create_shipment_items_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_26_183130_create_processes_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_27_163021_add_financial_columns_to_clients_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_27_164149_add_purchase_type_to_purchases_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_29_150420_add_item_id_to_stocks_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_29_175820_create_inspections_table_and_drop_legacy_material_tables.php:Zone.Identifier create mode 100644 database/migrations/2025_12_30_091821_create_positions_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_30_091822_add_position_type_to_common_codes.php:Zone.Identifier create mode 100644 database/migrations/2025_12_30_131009_add_key_to_positions_table.php:Zone.Identifier create mode 100644 database/migrations/2025_12_30_160802_add_is_hidden_to_roles_table.php:Zone.Identifier create mode 100644 database/migrations/2026_01_02_113722_add_is_overdue_to_clients_table.php:Zone.Identifier create mode 100644 database/migrations/2026_01_05_140111_add_price_fields_to_order_items_table.php:Zone.Identifier create mode 100644 database/migrations/2026_01_05_141500_add_quote_fields_to_orders_table.php:Zone.Identifier create mode 100644 database/migrations/2026_01_05_142000_add_order_id_to_quotes_table.php:Zone.Identifier create mode 100644 database/migrations/2026_01_08_000001_create_contracts_table.php:Zone.Identifier create mode 100644 database/migrations/2026_01_08_180607_create_process_items_table.php:Zone.Identifier create mode 100644 database/migrations/2026_01_09_162534_add_construction_fields_to_sites_table.php:Zone.Identifier create mode 100644 database/migrations/2026_01_09_171700_add_order_codes_to_common_codes.php:Zone.Identifier create mode 100644 database/migrations/2026_01_20_100001_add_columns_to_bank_accounts_table.php create mode 100644 database/migrations/2026_01_20_100001_add_columns_to_bank_accounts_table.php:Zone.Identifier create mode 100644 database/migrations/2026_01_20_100002_create_bank_transactions_table.php create mode 100644 database/migrations/2026_01_20_100002_create_bank_transactions_table.php:Zone.Identifier create mode 100644 database/migrations/2026_01_20_110001_create_fund_schedules_table.php create mode 100644 database/migrations/2026_01_20_110001_create_fund_schedules_table.php:Zone.Identifier create mode 100644 database/schema/mysql-schema.sql:Zone.Identifier create mode 100644 database/seeders/ApprovalTestDataSeeder.php:Zone.Identifier create mode 100644 database/seeders/BankAccountSeeder.php create mode 100644 database/seeders/BankAccountSeeder.php:Zone.Identifier create mode 100644 database/seeders/BpMesCategoryFieldsSeeder.php:Zone.Identifier create mode 100644 database/seeders/BpMesTenantStatFieldsSeeder.php:Zone.Identifier create mode 100644 database/seeders/CapabilityProfileSeeder.php:Zone.Identifier create mode 100644 database/seeders/CategorySeeder.php:Zone.Identifier create mode 100644 database/seeders/ComprehensiveAnalysisSeeder.php:Zone.Identifier create mode 100644 database/seeders/DatabaseSeeder.php:Zone.Identifier create mode 100644 database/seeders/DemoSystemSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyAttendanceSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyAttendanceSettingSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyBadDebtSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyBankAccountSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyBillSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyCardSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyClientGroupSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyClientSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyDepartmentSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyDepositSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyItemSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyLeaveGrantSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyLeaveSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyPaymentSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyPopupSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyPurchaseSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummySalarySeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummySaleSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyUserSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyWithdrawalSeeder.php:Zone.Identifier create mode 100644 database/seeders/Dummy/DummyWorkSettingSeeder.php:Zone.Identifier create mode 100644 database/seeders/DummyDataSeeder.php:Zone.Identifier create mode 100644 database/seeders/FolderSeeder.php:Zone.Identifier create mode 100644 database/seeders/FundScheduleSeeder.php create mode 100644 database/seeders/FundScheduleSeeder.php:Zone.Identifier create mode 100644 database/seeders/GlobalMenuTemplateSeeder.php:Zone.Identifier create mode 100644 database/seeders/ItemMasterSeeder.php:Zone.Identifier create mode 100644 database/seeders/ItemTypeSeeder.php:Zone.Identifier create mode 100644 database/seeders/PositionSeeder.php:Zone.Identifier create mode 100644 database/seeders/QuoteFormulaCategorySeeder.php:Zone.Identifier create mode 100644 database/seeders/QuoteFormulaItemSeeder.php:Zone.Identifier create mode 100644 database/seeders/QuoteFormulaMappingSeeder.php:Zone.Identifier create mode 100644 database/seeders/QuoteFormulaSeeder.php:Zone.Identifier create mode 100644 database/seeders/ReactMenuSeeder.php:Zone.Identifier create mode 100644 database/seeders/StockReceivingSeeder.php:Zone.Identifier create mode 100644 database/seeders/SystemFieldDefinitionSeeder.php:Zone.Identifier create mode 100644 lang/en/employee.php:Zone.Identifier create mode 100644 lang/en/error.php:Zone.Identifier create mode 100644 lang/en/message.php:Zone.Identifier create mode 100644 lang/ko/employee.php:Zone.Identifier create mode 100644 lang/ko/error.php:Zone.Identifier create mode 100644 lang/ko/message.php:Zone.Identifier create mode 100644 lang/ko/validation.php:Zone.Identifier create mode 100644 package-lock.json:Zone.Identifier create mode 100644 package.json:Zone.Identifier create mode 100644 phpunit.xml:Zone.Identifier create mode 100644 postcss.config.js:Zone.Identifier create mode 100644 pre-receive.bak:Zone.Identifier create mode 100644 public/.DS_Store:Zone.Identifier create mode 100644 public/.htaccess:Zone.Identifier create mode 100644 public/admin/css/animate.delay.css:Zone.Identifier create mode 100644 public/admin/css/animate.min.css:Zone.Identifier create mode 100644 public/admin/css/bootstrap-fileupload.min.css:Zone.Identifier create mode 100644 public/admin/css/bootstrap-override.css:Zone.Identifier create mode 100644 public/admin/css/bootstrap-timepicker.min.css:Zone.Identifier create mode 100644 public/admin/css/bootstrap.css:Zone.Identifier create mode 100644 public/admin/css/bootstrap.min.css:Zone.Identifier create mode 100644 public/admin/css/chosen.css:Zone.Identifier create mode 100644 public/admin/css/custom.css:Zone.Identifier create mode 100644 public/admin/css/font-awesome.css:Zone.Identifier create mode 100644 public/admin/css/font-awesome.min.css:Zone.Identifier create mode 100644 public/admin/css/jquery-ui-1.10.3.css:Zone.Identifier create mode 100644 public/admin/css/jquery.datatables.css:Zone.Identifier create mode 100644 public/admin/css/lato.css:Zone.Identifier create mode 100644 public/admin/css/layout.css:Zone.Identifier create mode 100644 public/admin/css/roboto.css:Zone.Identifier create mode 100644 public/admin/css/style.default.css:Zone.Identifier create mode 100644 public/admin/css/style.inverse.css:Zone.Identifier create mode 100644 public/admin/css/style_leave.css:Zone.Identifier create mode 100644 public/admin/css/style_login.css:Zone.Identifier create mode 100644 public/admin/css/tablesorter_2.31.3.css:Zone.Identifier create mode 100644 public/admin/css/toggles.css:Zone.Identifier create mode 100644 public/admin/font-awesome/css/font-awesome.css:Zone.Identifier create mode 100644 public/admin/font-awesome/css/font-awesome.min.css:Zone.Identifier create mode 100644 public/admin/font-awesome/fonts/FontAwesome.otf:Zone.Identifier create mode 100644 public/admin/font-awesome/fonts/fontawesome-webfont.eot:Zone.Identifier create mode 100644 public/admin/font-awesome/fonts/fontawesome-webfont.svg:Zone.Identifier create mode 100644 public/admin/font-awesome/fonts/fontawesome-webfont.ttf:Zone.Identifier create mode 100644 public/admin/font-awesome/fonts/fontawesome-webfont.woff:Zone.Identifier create mode 100644 public/admin/font-awesome/less/bordered-pulled.less:Zone.Identifier create mode 100644 public/admin/font-awesome/less/core.less:Zone.Identifier create mode 100644 public/admin/font-awesome/less/fixed-width.less:Zone.Identifier create mode 100644 public/admin/font-awesome/less/font-awesome.less:Zone.Identifier create mode 100644 public/admin/font-awesome/less/icons.less:Zone.Identifier create mode 100644 public/admin/font-awesome/less/larger.less:Zone.Identifier create mode 100644 public/admin/font-awesome/less/list.less:Zone.Identifier create mode 100644 public/admin/font-awesome/less/mixins.less:Zone.Identifier create mode 100644 public/admin/font-awesome/less/path.less:Zone.Identifier create mode 100644 public/admin/font-awesome/less/rotated-flipped.less:Zone.Identifier create mode 100644 public/admin/font-awesome/less/spinning.less:Zone.Identifier create mode 100644 public/admin/font-awesome/less/stacked.less:Zone.Identifier create mode 100644 public/admin/font-awesome/less/variables.less:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/_bordered-pulled.scss:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/_core.scss:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/_fixed-width.scss:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/_icons.scss:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/_larger.scss:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/_list.scss:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/_mixins.scss:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/_path.scss:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/_rotated-flipped.scss:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/_spinning.scss:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/_stacked.scss:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/_variables.scss:Zone.Identifier create mode 100644 public/admin/font-awesome/scss/font-awesome.scss:Zone.Identifier create mode 100644 public/admin/fonts/FontAwesome.otf:Zone.Identifier create mode 100644 public/admin/fonts/fontawesome-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/fontawesome-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/fontawesome-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/fontawesome-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/glyphicons-halflings-regular.eot:Zone.Identifier create mode 100644 public/admin/fonts/glyphicons-halflings-regular.svg:Zone.Identifier create mode 100644 public/admin/fonts/glyphicons-halflings-regular.ttf:Zone.Identifier create mode 100644 public/admin/fonts/glyphicons-halflings-regular.woff:Zone.Identifier create mode 100644 public/admin/fonts/index.html:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Bla-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Bla-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Bla-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Bla-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-BlaIta-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-BlaIta-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-BlaIta-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-BlaIta-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Bol-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Bol-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Bol-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Bol-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-BolIta-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-BolIta-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-BolIta-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-BolIta-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Hai-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Hai-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Hai-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Hai-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-HaiIta-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-HaiIta-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-HaiIta-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-HaiIta-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Lig-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Lig-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Lig-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Lig-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-LigIta-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-LigIta-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-LigIta-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-LigIta-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Reg-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Reg-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Reg-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-Reg-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-RegIta-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-RegIta-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-RegIta-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/lato/Lato-RegIta-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/lato/SIL Open Font License 1.1.txt:Zone.Identifier create mode 100644 public/admin/fonts/lato/index.html:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Google Android License.txt:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Black-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Black-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Black-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Black-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BlackItalic-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BlackItalic-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BlackItalic-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BlackItalic-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Bold-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Bold-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Bold-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Bold-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BoldCondensed-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BoldCondensed-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BoldCondensed-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BoldCondensed-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BoldCondensedItalic-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BoldCondensedItalic-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BoldCondensedItalic-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BoldCondensedItalic-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BoldItalic-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BoldItalic-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BoldItalic-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-BoldItalic-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Condensed-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Condensed-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Condensed-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Condensed-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-CondensedItalic-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-CondensedItalic-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-CondensedItalic-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-CondensedItalic-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Italic-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Italic-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Italic-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Italic-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Light-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Light-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Light-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Light-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-LightItalic-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-LightItalic-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-LightItalic-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-LightItalic-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Medium-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Medium-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Medium-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Medium-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-MediumItalic-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-MediumItalic-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-MediumItalic-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-MediumItalic-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Regular-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Regular-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Regular-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Regular-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Thin-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Thin-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Thin-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-Thin-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-ThinItalic-webfont.eot:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-ThinItalic-webfont.svg:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-ThinItalic-webfont.ttf:Zone.Identifier create mode 100644 public/admin/fonts/roboto/Roboto-ThinItalic-webfont.woff:Zone.Identifier create mode 100644 public/admin/fonts/roboto/index.html:Zone.Identifier create mode 100644 public/admin/fonts/roboto/roboto.css:Zone.Identifier create mode 100644 public/admin/images/box_line.png:Zone.Identifier create mode 100644 public/admin/images/box_line@2x.png:Zone.Identifier create mode 100644 public/admin/images/calendar-arrow.png:Zone.Identifier create mode 100644 public/admin/images/chosen-sprite.png:Zone.Identifier create mode 100644 public/admin/images/chosen-sprite@2x.png:Zone.Identifier create mode 100644 public/admin/images/close-white.png:Zone.Identifier create mode 100644 public/admin/images/dropdown-arrow.png:Zone.Identifier create mode 100644 public/admin/images/favicon.png:Zone.Identifier create mode 100644 public/admin/images/hormenu.jpg:Zone.Identifier create mode 100644 public/admin/images/icon-search.png:Zone.Identifier create mode 100644 public/admin/images/icon-search@2x.png:Zone.Identifier create mode 100644 public/admin/images/index.html:Zone.Identifier create mode 100644 public/admin/images/is-document.png:Zone.Identifier create mode 100644 public/admin/images/is-money.png:Zone.Identifier create mode 100644 public/admin/images/is-user.png:Zone.Identifier create mode 100644 public/admin/images/locked.png:Zone.Identifier create mode 100644 public/admin/images/minus.png:Zone.Identifier create mode 100644 public/admin/images/minus@2x.png:Zone.Identifier create mode 100644 public/admin/images/plus-white.png:Zone.Identifier create mode 100644 public/admin/images/plus-white@2x.png:Zone.Identifier create mode 100644 public/admin/images/plus.png:Zone.Identifier create mode 100644 public/admin/images/plus@2x.png:Zone.Identifier create mode 100644 public/admin/images/screen.png:Zone.Identifier create mode 100644 public/admin/images/sort_asc.png:Zone.Identifier create mode 100644 public/admin/images/sort_asc_disabled.png:Zone.Identifier create mode 100644 public/admin/images/sort_both.png:Zone.Identifier create mode 100644 public/admin/images/sort_desc.png:Zone.Identifier create mode 100644 public/admin/images/sort_desc_disabled.png:Zone.Identifier create mode 100644 public/admin/images/spritemap.png:Zone.Identifier create mode 100644 public/admin/images/spritemap@2x.png:Zone.Identifier create mode 100644 public/admin/images/themeforest.png:Zone.Identifier create mode 100644 public/admin/images/themepixels.png:Zone.Identifier create mode 100644 public/admin/images/uploadfile.png:Zone.Identifier create mode 100644 public/admin/images/uploadfile@2x.png:Zone.Identifier create mode 100644 public/admin/images/user.png:Zone.Identifier create mode 100644 public/admin/js/board/board.js:Zone.Identifier create mode 100644 public/admin/js/bootstrap-fileupload.min.js:Zone.Identifier create mode 100644 public/admin/js/bootstrap-timepicker.min.js:Zone.Identifier create mode 100644 public/admin/js/bootstrap.js:Zone.Identifier create mode 100644 public/admin/js/bootstrap.min.js:Zone.Identifier create mode 100644 public/admin/js/chosen.jquery.min.js:Zone.Identifier create mode 100644 public/admin/js/company/company.js:Zone.Identifier create mode 100644 public/admin/js/custom.js:Zone.Identifier create mode 100644 public/admin/js/highchart/code/accessibility.js.map:Zone.Identifier create mode 100644 public/admin/js/highchart/code/accessibility.js:Zone.Identifier create mode 100644 public/admin/js/highchart/code/accessibility.src.js:Zone.Identifier create mode 100644 public/admin/js/highchart/code/export-data.js.map:Zone.Identifier create mode 100644 public/admin/js/highchart/code/export-data.js:Zone.Identifier create mode 100644 public/admin/js/highchart/code/export-data.src.js:Zone.Identifier create mode 100644 public/admin/js/highchart/code/exporting.js.map:Zone.Identifier create mode 100644 public/admin/js/highchart/code/exporting.js:Zone.Identifier create mode 100644 public/admin/js/highchart/code/exporting.src.js:Zone.Identifier create mode 100644 public/admin/js/highchart/code/pattern-fill.js.map:Zone.Identifier create mode 100644 public/admin/js/highchart/code/pattern-fill.js:Zone.Identifier create mode 100644 public/admin/js/highchart/code/pattern-fill.src.js:Zone.Identifier create mode 100644 public/admin/js/highchart/highcharts-gantt.js.map:Zone.Identifier create mode 100644 public/admin/js/highchart/highcharts-gantt.js:Zone.Identifier create mode 100644 public/admin/js/highchart/highcharts-gantt.src.js:Zone.Identifier create mode 100644 public/admin/js/highchart/highcharts.js:Zone.Identifier create mode 100644 public/admin/js/highcharts.js:Zone.Identifier create mode 100644 public/admin/js/jquery-1.10.2.min.js:Zone.Identifier create mode 100644 public/admin/js/jquery-migrate-1.2.1.min.js:Zone.Identifier create mode 100644 public/admin/js/jquery-ui-1.10.3.min.js:Zone.Identifier create mode 100644 public/admin/js/jquery.cookies.js:Zone.Identifier create mode 100644 public/admin/js/jquery.sparkline.min.js:Zone.Identifier create mode 100644 public/admin/js/main/dashboard.js:Zone.Identifier create mode 100644 public/admin/js/meeting/mtg_mn.js:Zone.Identifier create mode 100644 public/admin/js/member/member.js:Zone.Identifier create mode 100644 public/admin/js/modernizr.min.js:Zone.Identifier create mode 100644 public/admin/js/plan/daily.js:Zone.Identifier create mode 100644 public/admin/js/plan/info.js:Zone.Identifier create mode 100644 public/admin/js/retina.min.js:Zone.Identifier create mode 100644 public/admin/js/screenfull.min.js:Zone.Identifier create mode 100644 public/admin/js/stats/common.js:Zone.Identifier create mode 100644 public/admin/js/status/daily-list.js:Zone.Identifier create mode 100644 public/admin/js/status/task-list.js:Zone.Identifier create mode 100644 public/admin/js/toggles.min.js:Zone.Identifier create mode 100644 public/api-docs/index.html:Zone.Identifier create mode 100644 public/develop/cicd-pipeline-flow.html:Zone.Identifier create mode 100644 public/develop/disaster-recovery-plan.md:Zone.Identifier create mode 100644 public/develop/index.php:Zone.Identifier create mode 100644 public/develop/meeting-presentation-summary.html:Zone.Identifier create mode 100644 public/develop/network-topology-diagram.html:Zone.Identifier create mode 100644 public/develop/server-spec-cost-analysis.html:Zone.Identifier create mode 100644 public/develop/system-architecture-diagram.html:Zone.Identifier create mode 100644 public/favicon.ico:Zone.Identifier create mode 100644 public/html/.DS_Store:Zone.Identifier create mode 100644 public/html/inc/footer.php:Zone.Identifier create mode 100644 public/html/inc/header.php:Zone.Identifier create mode 100644 public/html/pages/home.html:Zone.Identifier create mode 100644 public/index.php:Zone.Identifier create mode 100644 public/robots.txt:Zone.Identifier create mode 100644 public/storage:Zone.Identifier create mode 100644 public/swagger-ui/favicon-16x16.png:Zone.Identifier create mode 100644 public/swagger-ui/favicon-32x32.png:Zone.Identifier create mode 100644 public/swagger-ui/index.css:Zone.Identifier create mode 100644 public/swagger-ui/index.html:Zone.Identifier create mode 100644 public/swagger-ui/oauth2-redirect.html:Zone.Identifier create mode 100644 public/swagger-ui/swagger-initializer.js:Zone.Identifier create mode 100644 public/swagger-ui/swagger-ui-bundle.js.map:Zone.Identifier create mode 100644 public/swagger-ui/swagger-ui-bundle.js:Zone.Identifier create mode 100644 public/swagger-ui/swagger-ui-es-bundle-core.js.map:Zone.Identifier create mode 100644 public/swagger-ui/swagger-ui-es-bundle-core.js:Zone.Identifier create mode 100644 public/swagger-ui/swagger-ui-es-bundle.js.map:Zone.Identifier create mode 100644 public/swagger-ui/swagger-ui-es-bundle.js:Zone.Identifier create mode 100644 public/swagger-ui/swagger-ui-standalone-preset.js.map:Zone.Identifier create mode 100644 public/swagger-ui/swagger-ui-standalone-preset.js:Zone.Identifier create mode 100644 public/swagger-ui/swagger-ui.css.map:Zone.Identifier create mode 100644 public/swagger-ui/swagger-ui.css:Zone.Identifier create mode 100644 public/swagger-ui/swagger-ui.js.map:Zone.Identifier create mode 100644 public/swagger-ui/swagger-ui.js:Zone.Identifier create mode 100644 public/tenant/api/login_process.php:Zone.Identifier create mode 100644 public/tenant/api/register_process.php:Zone.Identifier create mode 100644 public/tenant/approval/instances.php:Zone.Identifier create mode 100644 public/tenant/approval/objects.php:Zone.Identifier create mode 100644 public/tenant/approval/pool.php:Zone.Identifier create mode 100644 public/tenant/approval/rules.php:Zone.Identifier create mode 100644 public/tenant/assets/js/permission_menu.js:Zone.Identifier create mode 100644 public/tenant/category/category_list.php:Zone.Identifier create mode 100644 public/tenant/category/subcategory_list.php:Zone.Identifier create mode 100644 public/tenant/inc/config.php:Zone.Identifier create mode 100644 public/tenant/inc/footer.php:Zone.Identifier create mode 100644 public/tenant/inc/header.php:Zone.Identifier create mode 100644 public/tenant/inc/navi.php:Zone.Identifier create mode 100644 public/tenant/index.php:Zone.Identifier create mode 100644 public/tenant/inventory/defective.php:Zone.Identifier create mode 100644 public/tenant/inventory/stock.php:Zone.Identifier create mode 100644 public/tenant/material/inspection_list.php:Zone.Identifier create mode 100644 public/tenant/material/inventory_status.php:Zone.Identifier create mode 100644 public/tenant/material/list.php:Zone.Identifier create mode 100644 public/tenant/member/dashboard.php:Zone.Identifier create mode 100644 public/tenant/member/intro.php:Zone.Identifier create mode 100644 public/tenant/member/login.php:Zone.Identifier create mode 100644 public/tenant/member/logout.php:Zone.Identifier create mode 100644 public/tenant/member/profile_edit.php:Zone.Identifier create mode 100644 public/tenant/member/register.php:Zone.Identifier create mode 100644 public/tenant/member/tenant_add_process.php:Zone.Identifier create mode 100644 public/tenant/member/tenant_select.php:Zone.Identifier create mode 100644 public/tenant/member/tenant_select_process.php:Zone.Identifier create mode 100644 public/tenant/member/withdraw.php:Zone.Identifier create mode 100644 public/tenant/order/edit.php:Zone.Identifier create mode 100644 public/tenant/order/estimate.php:Zone.Identifier create mode 100644 public/tenant/order/estimate_form.php:Zone.Identifier create mode 100644 public/tenant/order/manage.php:Zone.Identifier create mode 100644 public/tenant/order/status.php:Zone.Identifier create mode 100644 public/tenant/permission/analyze.php:Zone.Identifier create mode 100644 public/tenant/permission/approver.php:Zone.Identifier create mode 100644 public/tenant/permission/audit.php:Zone.Identifier create mode 100644 public/tenant/permission/department.php:Zone.Identifier create mode 100644 public/tenant/permission/role.php:Zone.Identifier create mode 100644 public/tenant/permission/structure.php:Zone.Identifier create mode 100644 public/tenant/permission/tenant_menu.php:Zone.Identifier create mode 100644 public/tenant/permission/user.php:Zone.Identifier create mode 100644 public/tenant/process/process_form.php:Zone.Identifier create mode 100644 public/tenant/process/process_settings.php:Zone.Identifier create mode 100644 public/tenant/process/processes.php:Zone.Identifier create mode 100644 public/tenant/process/task_form.php:Zone.Identifier create mode 100644 public/tenant/process/tasks.php:Zone.Identifier create mode 100644 public/tenant/product/bending.php:Zone.Identifier create mode 100644 public/tenant/product/bom.php:Zone.Identifier create mode 100644 public/tenant/product/bom_combined.php:Zone.Identifier create mode 100644 public/tenant/product/bom_editor.php:Zone.Identifier create mode 100644 public/tenant/product/code_lot.php:Zone.Identifier create mode 100644 public/tenant/product/model.php:Zone.Identifier create mode 100644 public/tenant/product/model_list.php:Zone.Identifier create mode 100644 public/tenant/product/product_price.php:Zone.Identifier create mode 100644 public/tenant/production/bend_work.php:Zone.Identifier create mode 100644 public/tenant/production/mid_inspection.php:Zone.Identifier create mode 100644 public/tenant/production/process_detail.php:Zone.Identifier create mode 100644 public/tenant/production/screen_progress.php:Zone.Identifier create mode 100644 public/tenant/production/screen_work.php:Zone.Identifier create mode 100644 public/tenant/production/slat_work.php:Zone.Identifier create mode 100644 public/tenant/production/work_instruction.php:Zone.Identifier create mode 100644 public/tenant/quality/docs.php:Zone.Identifier create mode 100644 public/tenant/quality/record.php:Zone.Identifier create mode 100644 public/tenant/quality/request.php:Zone.Identifier create mode 100644 public/tenant/quality/schedule.php:Zone.Identifier create mode 100644 public/tenant/settings/member_fields.php:Zone.Identifier create mode 100644 public/tenant/settings/option_groups.php:Zone.Identifier create mode 100644 public/tenant/shipment/monthly_schedule.php:Zone.Identifier create mode 100644 public/tenant/shipment/status.php:Zone.Identifier create mode 100644 public/tenant/subscription/list.php:Zone.Identifier create mode 100644 public/tenant/subscription/tenant_list.php:Zone.Identifier create mode 100644 public/tenant/subscription/tenant_product_list.php:Zone.Identifier create mode 100644 public/tenant/tenant/department_list.php:Zone.Identifier create mode 100644 public/tenant/tenant/edit.php:Zone.Identifier create mode 100644 public/tenant/tenant/join.php:Zone.Identifier create mode 100644 public/tenant/tenant/option.php:Zone.Identifier create mode 100644 public/tenant/tenant/role_add.php:Zone.Identifier create mode 100644 public/tenant/tenant/role_delete.php:Zone.Identifier create mode 100644 public/tenant/tenant/role_edit.php:Zone.Identifier create mode 100644 public/tenant/tenant/role_list.php:Zone.Identifier create mode 100644 public/tenant/tenant/subscribe.php:Zone.Identifier create mode 100644 public/tenant/tenant/user_edit.php:Zone.Identifier create mode 100644 public/tenant/tenant/user_list.php:Zone.Identifier create mode 100644 public/tenant/tenant/user_unmap.php:Zone.Identifier create mode 100644 public/tenant/tenant/withdraw.php:Zone.Identifier create mode 100644 public/tenant/tenant_base.html:Zone.Identifier create mode 100644 public/tenant/test.html:Zone.Identifier create mode 100644 relationships.txt:Zone.Identifier create mode 100644 resources/css/app.css:Zone.Identifier create mode 100644 resources/js/app.js:Zone.Identifier create mode 100644 resources/js/bootstrap.js:Zone.Identifier create mode 100644 resources/markdown/policy.md:Zone.Identifier create mode 100644 resources/markdown/terms.md:Zone.Identifier create mode 100644 resources/views/api/api-token-manager.blade.php:Zone.Identifier create mode 100644 resources/views/api/index.blade.php:Zone.Identifier create mode 100644 resources/views/auth/confirm-password.blade.php:Zone.Identifier create mode 100644 resources/views/auth/forgot-password.blade.php:Zone.Identifier create mode 100644 resources/views/auth/login.blade.php:Zone.Identifier create mode 100644 resources/views/auth/register.blade.php:Zone.Identifier create mode 100644 resources/views/auth/reset-password.blade.php:Zone.Identifier create mode 100644 resources/views/auth/two-factor-challenge.blade.php:Zone.Identifier create mode 100644 resources/views/auth/verify-email.blade.php:Zone.Identifier create mode 100644 resources/views/components/action-message.blade.php:Zone.Identifier create mode 100644 resources/views/components/action-section.blade.php:Zone.Identifier create mode 100644 resources/views/components/application-logo.blade.php:Zone.Identifier create mode 100644 resources/views/components/application-mark.blade.php:Zone.Identifier create mode 100644 resources/views/components/authentication-card-logo.blade.php:Zone.Identifier create mode 100644 resources/views/components/authentication-card.blade.php:Zone.Identifier create mode 100644 resources/views/components/banner.blade.php:Zone.Identifier create mode 100644 resources/views/components/button.blade.php:Zone.Identifier create mode 100644 resources/views/components/checkbox.blade.php:Zone.Identifier create mode 100644 resources/views/components/confirmation-modal.blade.php:Zone.Identifier create mode 100644 resources/views/components/confirms-password.blade.php:Zone.Identifier create mode 100644 resources/views/components/danger-button.blade.php:Zone.Identifier create mode 100644 resources/views/components/dialog-modal.blade.php:Zone.Identifier create mode 100644 resources/views/components/dropdown-link.blade.php:Zone.Identifier create mode 100644 resources/views/components/dropdown.blade.php:Zone.Identifier create mode 100644 resources/views/components/form-section.blade.php:Zone.Identifier create mode 100644 resources/views/components/input-error.blade.php:Zone.Identifier create mode 100644 resources/views/components/input.blade.php:Zone.Identifier create mode 100644 resources/views/components/label.blade.php:Zone.Identifier create mode 100644 resources/views/components/modal.blade.php:Zone.Identifier create mode 100644 resources/views/components/nav-link.blade.php:Zone.Identifier create mode 100644 resources/views/components/responsive-nav-link.blade.php:Zone.Identifier create mode 100644 resources/views/components/secondary-button.blade.php:Zone.Identifier create mode 100644 resources/views/components/section-border.blade.php:Zone.Identifier create mode 100644 resources/views/components/section-title.blade.php:Zone.Identifier create mode 100644 resources/views/components/switchable-team.blade.php:Zone.Identifier create mode 100644 resources/views/components/validation-errors.blade.php:Zone.Identifier create mode 100644 resources/views/components/welcome.blade.php:Zone.Identifier create mode 100644 resources/views/dashboard.blade.php:Zone.Identifier create mode 100644 resources/views/emails/team-invitation.blade.php:Zone.Identifier create mode 100644 resources/views/layouts/app.blade.php:Zone.Identifier create mode 100644 resources/views/layouts/app.old.blade.php:Zone.Identifier create mode 100644 resources/views/layouts/footer.blade.php:Zone.Identifier create mode 100644 resources/views/layouts/guest.blade.php:Zone.Identifier create mode 100644 resources/views/layouts/left.blade.php:Zone.Identifier create mode 100644 resources/views/navigation-menu.blade.php:Zone.Identifier create mode 100644 resources/views/policy.blade.php:Zone.Identifier create mode 100644 resources/views/profile/delete-user-form.blade.php:Zone.Identifier create mode 100644 resources/views/profile/logout-other-browser-sessions-form.blade.php:Zone.Identifier create mode 100644 resources/views/profile/show.blade.php:Zone.Identifier create mode 100644 resources/views/profile/two-factor-authentication-form.blade.php:Zone.Identifier create mode 100644 resources/views/profile/update-password-form.blade.php:Zone.Identifier create mode 100644 resources/views/profile/update-profile-information-form.blade.php:Zone.Identifier create mode 100644 resources/views/terms.blade.php:Zone.Identifier create mode 100644 resources/views/welcome.blade.php:Zone.Identifier create mode 100644 routes/api.php:Zone.Identifier create mode 100644 routes/console.php:Zone.Identifier create mode 100644 routes/web.php:Zone.Identifier create mode 100644 storage/api-docs/api-docs-v1.json:Zone.Identifier create mode 100644 storage/api-docs/api-docs.json:Zone.Identifier create mode 100644 tailwind.config.js:Zone.Identifier create mode 100644 vite.config.js:Zone.Identifier diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..52b5f7c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,18 @@ +node_modules +vendor +.git +.env +.env.backup +.phpunit.result.cache +storage/logs/* +storage/framework/cache/* +storage/framework/sessions/* +storage/framework/views/* +bootstrap/cache/* +.DS_Store +Thumbs.db +.idea +.vscode +*.log +npm-debug.log* +yarn-debug.log* diff --git a/.dockerignore:Zone.Identifier b/.dockerignore:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xservice->getMaterials($request->all()); + }, __('message.material.fetched')); + } + + public function store(MaterialStoreRequest $request) + { + return ApiResponse::handle(function () use ($request) { + // 동적 필드 지원을 위해 전체 입력값 전달 (Service에서 검증) + return $this->service->setMaterial($request->all()); + }, __('message.material.created')); + } + + public function show(int $id) + { + return ApiResponse::handle(function () use ($id) { + return $this->service->getMaterial($id); + }, __('message.material.fetched')); + } + + public function update(MaterialUpdateRequest $request, int $id) + { + return ApiResponse::handle(function () use ($request, $id) { + // 동적 필드 지원을 위해 전체 입력값 전달 (Service에서 검증) + return $this->service->updateMaterial($id, $request->all()); + }, __('message.material.updated')); + } + + public function destroy(int $id) + { + return ApiResponse::handle(function () use ($id) { + return $this->service->destroyMaterial($id); + }, __('message.material.deleted')); + } +} diff --git a/app/Http/Controllers/Api/V1/MaterialController.php:Zone.Identifier b/app/Http/Controllers/Api/V1/MaterialController.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xservice->index($id, $request->all()); + }, 'BOM 항목 목록'); + } + + // POST /products/{id}/bom/items/bulk + public function bulkUpsert(int $id, Request $request) + { + return ApiResponse::handle(function () use ($id, $request) { + return $this->service->bulkUpsert($id, $request->input('items', [])); + }, 'BOM 일괄 업서트'); + } + + // PATCH /products/{id}/bom/items/{item} + public function update(int $id, int $item, Request $request) + { + return ApiResponse::handle(function () use ($id, $item, $request) { + return $this->service->update($id, $item, $request->all()); + }, 'BOM 항목 수정'); + } + + // DELETE /products/{id}/bom/items/{item} + public function destroy(int $id, int $item) + { + return ApiResponse::handle(function () use ($id, $item) { + $this->service->destroy($id, $item); + + return 'success'; + }, 'BOM 항목 삭제'); + } + + // POST /products/{id}/bom/items/reorder + public function reorder(int $id, Request $request) + { + return ApiResponse::handle(function () use ($id, $request) { + $this->service->reorder($id, $request->input('items', [])); + + return 'success'; + }, 'BOM 정렬 변경'); + } + + // GET /products/{id}/bom/summary + public function summary(int $id) + { + return ApiResponse::handle(function () use ($id) { + return $this->service->summary($id); + }, 'BOM 요약'); + } + + // GET /products/{id}/bom/validate + public function validateBom(int $id) + { + return ApiResponse::handle(function () use ($id) { + return $this->service->validateBom($id); + }, 'BOM 유효성 검사'); + } + + /** + * POST /api/v1/products/{id}/bom + * BOM 구성 저장 (기존 전체 삭제 후 재등록) + */ + public function replace(Request $request, int $id) + { + return ApiResponse::handle(function () use ($request, $id) { + // 서비스에서 트랜잭션 처리 + 예외는 글로벌 핸들러로 + return $this->service->replaceBom($id, $request->all()); + }, __('message.bom.creat')); + } + + /** 특정 제품 BOM에서 사용 중인 카테고리 목록 */ + public function listCategories(int $id) + { + return ApiResponse::handle(function () use ($id) { + return $this->service->listCategoriesForProduct($id); + }, __('message.bom.fetch')); + } + + /** 테넌트 전역 카테고리 추천(히스토리) */ + public function suggestCategories(Request $request) + { + return ApiResponse::handle(function () use ($request) { + $q = $request->query('q'); + $limit = (int) ($request->query('limit', 20)); + + return $this->service->listCategoriesForTenant($q, $limit); + }, __('message.bom.fetch')); + } + + /** Bom Tree */ + public function tree(Request $request, int $id) + { + return ApiResponse::handle( + function () use ($request, $id) { + return $this->service->tree($request, $id); + }, __('message.bom.fetch') + ); + } +} diff --git a/app/Http/Controllers/Api/V1/ProductBomItemController.php:Zone.Identifier b/app/Http/Controllers/Api/V1/ProductBomItemController.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xservice->getCategory($request); + }, __('message.product.category_fetched')); + } + + // GET /products + public function index(Request $request) + { + return ApiResponse::handle(function () use ($request) { + return $this->service->index($request->all()); + }, __('message.product.fetched')); + } + + // POST /products + public function store(ProductStoreRequest $request) + { + return ApiResponse::handle(function () use ($request) { + return $this->service->store($request->validated()); + }, __('message.product.created')); + } + + // GET /products/{id} + public function show(int $id) + { + return ApiResponse::handle(function () use ($id) { + return $this->service->show($id); + }, __('message.product.fetched')); + } + + // PATCH /products/{id} + public function update(int $id, ProductUpdateRequest $request) + { + return ApiResponse::handle(function () use ($id, $request) { + return $this->service->update($id, $request->validated()); + }, __('message.product.updated')); + } + + // DELETE /products/{id} + public function destroy(int $id) + { + return ApiResponse::handle(function () use ($id) { + $this->service->destroy($id); + + return 'success'; + }, __('message.product.deleted')); + } + + // GET /products/search + public function search(Request $request) + { + return ApiResponse::handle(function () use ($request) { + return $this->service->search($request->all()); + }, __('message.product.searched')); + } + + // Note: toggle 메서드는 is_active 필드 제거로 인해 비활성화됨 + // 필요시 attributes JSON이나 별도 필드로 구현 + // POST /products/{id}/toggle + // public function toggle(int $id) + // { + // return ApiResponse::handle(function () use ($id) { + // return $this->service->toggle($id); + // }, __('message.product.toggled')); + // } +} diff --git a/app/Http/Controllers/Api/V1/ProductController.php:Zone.Identifier b/app/Http/Controllers/Api/V1/ProductController.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2x 'nullable|integer', + 'name' => 'required|string|max:100', + 'unit' => 'required|string|max:20', + 'is_inspection' => 'nullable|in:Y,N', + 'search_tag' => 'nullable|string|max:255', + 'remarks' => 'nullable|string|max:500', + 'attributes' => 'nullable|array', + 'attributes.*.label' => 'required|string|max:50', + 'attributes.*.value' => 'required|string|max:100', + 'attributes.*.unit' => 'nullable|string|max:20', + 'options' => 'nullable|array', + 'material_code' => 'nullable|string|max:30', + 'specification' => 'nullable|string|max:255', + ]; + } +} diff --git a/app/Http/Requests/Material/MaterialStoreRequest.php:Zone.Identifier b/app/Http/Requests/Material/MaterialStoreRequest.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2x 'nullable|integer', + 'name' => 'sometimes|string|max:100', + 'unit' => 'sometimes|string|max:20', + 'is_inspection' => 'nullable|in:Y,N', + 'search_tag' => 'nullable|string|max:255', + 'remarks' => 'nullable|string|max:500', + 'attributes' => 'nullable|array', + 'attributes.*.label' => 'required|string|max:50', + 'attributes.*.value' => 'required|string|max:100', + 'attributes.*.unit' => 'nullable|string|max:20', + 'options' => 'nullable|array', + 'material_code' => 'nullable|string|max:30', + 'specification' => 'nullable|string|max:255', + ]; + } +} diff --git a/app/Http/Requests/Material/MaterialUpdateRequest.php:Zone.Identifier b/app/Http/Requests/Material/MaterialUpdateRequest.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2x 'required|string|max:30', + 'name' => 'required|string|max:100', + 'unit' => 'nullable|string|max:10', + 'category_id' => 'required|integer', + 'product_type' => 'required|string|max:30', + 'description' => 'nullable|string|max:255', + + // 상태 플래그 + 'is_sellable' => 'nullable|boolean', + 'is_purchasable' => 'nullable|boolean', + 'is_producible' => 'nullable|boolean', + + // 하이브리드 구조: 고정 필드 + 'safety_stock' => 'nullable|integer|min:0', + 'lead_time' => 'nullable|integer|min:0', + 'is_variable_size' => 'nullable|boolean', + 'product_category' => 'nullable|string|max:20', + 'part_type' => 'nullable|string|max:20', + + // 하이브리드 구조: 동적 필드 + 'attributes' => 'nullable|array', + 'attributes_archive' => 'nullable|array', + ]; + } +} diff --git a/app/Http/Requests/Product/ProductStoreRequest.php:Zone.Identifier b/app/Http/Requests/Product/ProductStoreRequest.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2x 'sometimes|string|max:30', + 'name' => 'sometimes|string|max:100', + 'unit' => 'nullable|string|max:10', + 'category_id' => 'sometimes|integer', + 'product_type' => 'sometimes|string|max:30', + 'description' => 'nullable|string|max:255', + + // 상태 플래그 + 'is_sellable' => 'nullable|boolean', + 'is_purchasable' => 'nullable|boolean', + 'is_producible' => 'nullable|boolean', + + // 하이브리드 구조: 고정 필드 + 'safety_stock' => 'nullable|integer|min:0', + 'lead_time' => 'nullable|integer|min:0', + 'is_variable_size' => 'nullable|boolean', + 'product_category' => 'nullable|string|max:20', + 'part_type' => 'nullable|string|max:20', + + // 하이브리드 구조: 동적 필드 + 'attributes' => 'nullable|array', + 'attributes_archive' => 'nullable|array', + ]; + } +} diff --git a/app/Http/Requests/Product/ProductUpdateRequest.php:Zone.Identifier b/app/Http/Requests/Product/ProductUpdateRequest.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2x 'array', + 'options' => 'array', + 'is_active' => 'boolean', + ]; + + protected $hidden = [ + 'deleted_at', + ]; + + // 카테고리 + public function category() + { + return $this->belongsTo(Category::class); + } + + // 자재 입고 내역 + public function receipts() + { + return $this->hasMany(MaterialReceipt::class, 'material_id'); + } + + // 로트 관리 + public function lots() + { + return $this->hasMany(Lot::class, 'material_id'); + } + + // 파일 목록 (N:M, 폴리모픽) + public function files() + { + return $this->morphMany(File::class, 'fileable'); + } + + // 태그 목록 (N:M, 폴리모픽) + public function tags() + { + return $this->morphToMany(Tag::class, 'taggable'); + } +} diff --git a/app/Models/Materials/Material.php:Zone.Identifier b/app/Models/Materials/Material.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xbelongsTo(MaterialReceipt::class, 'receipt_id'); + } + + // 검사 항목 + public function items() + { + return $this->hasMany(MaterialInspectionItem::class, 'inspection_id'); + } +} diff --git a/app/Models/Materials/MaterialInspection.php:Zone.Identifier b/app/Models/Materials/MaterialInspection.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xbelongsTo(MaterialInspection::class, 'inspection_id'); + } +} diff --git a/app/Models/Materials/MaterialInspectionItem.php:Zone.Identifier b/app/Models/Materials/MaterialInspectionItem.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xbelongsTo(Material::class, 'material_id'); + } + + // 수입검사 내역 + public function inspections() + { + return $this->hasMany(MaterialInspection::class, 'receipt_id'); + } +} diff --git a/app/Models/Materials/MaterialReceipt.php:Zone.Identifier b/app/Models/Materials/MaterialReceipt.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2x 'array', + 'is_active' => 'boolean', + ]; + + // 관계: 상위 코드 + public function parent() + { + return $this->belongsTo(self::class, 'parent_id'); + } + + // 관계: 하위 코드들 + public function children() + { + return $this->hasMany(self::class, 'parent_id'); + } +} diff --git a/app/Models/Products/CommonCode.php:Zone.Identifier b/app/Models/Products/CommonCode.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xbelongsTo(CommonCode::class, 'category_id'); + } + + public function partType() + { + return $this->belongsTo(CommonCode::class, 'part_type_id'); + } + + // 태그 목록 (N:M, 폴리모픽) + public function tags() + { + return $this->morphToMany(Tag::class, 'taggable'); + } +} diff --git a/app/Models/Products/Part.php:Zone.Identifier b/app/Models/Products/Part.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2x 'array', + 'attributes_archive' => 'array', + 'options' => 'array', + 'bom' => 'array', + 'bending_details' => 'array', + 'certification_start_date' => 'date', + 'certification_end_date' => 'date', + 'is_sellable' => 'boolean', + 'is_purchasable' => 'boolean', + 'is_producible' => 'boolean', + 'is_variable_size' => 'boolean', + 'is_active' => 'boolean', + ]; + + protected $hidden = [ + 'deleted_at', + ]; + + // 분류 + public function category() + { + return $this->belongsTo(Category::class, 'category_id'); + } + + // BOM (자기참조) — 라인 모델 경유 + public function componentLines() + { + return $this->hasMany(ProductComponent::class, 'parent_product_id')->orderBy('sort_order'); + } + + // 라인들 + public function parentLines() + { + return $this->hasMany(ProductComponent::class, 'child_product_id'); + } // 나를 쓰는 상위 라인들 + + // 편의: 직접 children/parents 제품에 접근 + public function children() + { + return $this->belongsToMany( + self::class, 'product_components', 'parent_product_id', 'child_product_id' + )->withPivot(['quantity', 'sort_order', 'is_default']) + ->withTimestamps(); + } + + public function parents() + { + return $this->belongsToMany( + self::class, 'product_components', 'child_product_id', 'parent_product_id' + )->withPivot(['quantity', 'sort_order', 'is_default']) + ->withTimestamps(); + } + + // 파일 / 태그 (폴리모픽) + public function files() + { + return $this->morphMany(File::class, 'fileable'); + } + + public function tags() + { + return $this->morphToMany(Tag::class, 'taggable'); + } + + // 스코프 + public function scopeType($q, string $type) + { + return $q->where('product_type', $type); + } + + public function scopeSellable($q) + { + return $q->where('is_sellable', 1); + } + + public function scopePurchasable($q) + { + return $q->where('is_purchasable', 1); + } + + public function scopeProducible($q) + { + return $q->where('is_producible', 1); + } +} diff --git a/app/Models/Products/Product.php:Zone.Identifier b/app/Models/Products/Product.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2x 'decimal:6', + 'attributes' => 'array', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + 'deleted_at' => 'datetime', + ]; + + protected $hidden = [ + 'deleted_at', + ]; + + /** + * 상위 제품 (모델/제품) + */ + public function parentProduct() + { + return $this->belongsTo(Product::class, 'parent_product_id'); + } + + /** + * 참조된 제품 또는 자재를 동적으로 가져오기 + * ref_type에 따라 Product 또는 Material을 반환 + */ + public function referencedItem() + { + if ($this->ref_type === 'PRODUCT') { + return $this->belongsTo(Product::class, 'ref_id'); + } elseif ($this->ref_type === 'MATERIAL') { + return $this->belongsTo(Material::class, 'ref_id'); + } + + return null; + } + + /** + * 하위 제품 (ref_type = PRODUCT일 때만) + */ + public function product() + { + return $this->belongsTo(Product::class, 'ref_id') + ->where('ref_type', 'PRODUCT'); + } + + /** + * 하위 자재 (ref_type = MATERIAL일 때만) + */ + public function material() + { + return $this->belongsTo(Material::class, 'ref_id') + ->where('ref_type', 'MATERIAL'); + } + + // --------------------------------------------------- + // 🔎 Query Scopes + // --------------------------------------------------- + + /** + * 제품 BOM 아이템만 + */ + public function scopeProducts($query) + { + return $query->where('ref_type', 'PRODUCT'); + } + + /** + * 자재 BOM 아이템만 + */ + public function scopeMaterials($query) + { + return $query->where('ref_type', 'MATERIAL'); + } + + /** + * 특정 상위 제품의 BOM + */ + public function scopeForParent($query, int $parentProductId) + { + return $query->where('parent_product_id', $parentProductId); + } +} diff --git a/app/Models/Products/ProductComponent.php:Zone.Identifier b/app/Models/Products/ProductComponent.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xtenantId(); + + // 1. SystemFields에서 테이블 고정 컬럼 + $systemFields = SystemFields::getReservedKeys($sourceTable); + + // 2. ItemField에서 storage_type='column'인 필드의 field_key 조회 + $columnFields = ItemField::where('tenant_id', $tenantId) + ->where('source_table', $sourceTable) + ->where('storage_type', 'column') + ->whereNotNull('field_key') + ->pluck('field_key') + ->toArray(); + + // 3. 추가적인 API 전용 필드 + $apiFields = ['item_type', 'type_code', 'bom', 'product_type']; + + return array_unique(array_merge($systemFields, $columnFields, $apiFields)); + } + + /** + * 동적 필드 추출 + */ + private function extractDynamicOptions(array $params, string $sourceTable): array + { + $knownFields = $this->getKnownFields($sourceTable); + + $dynamicOptions = []; + foreach ($params as $key => $value) { + if (! in_array($key, $knownFields) && $value !== null && $value !== '') { + $dynamicOptions[$key] = $value; + } + } + + return $dynamicOptions; + } + + /** + * 기존 options와 동적 필드 병합 + */ + private function mergeOptionsWithDynamic($existingOptions, array $dynamicOptions): array + { + if (! is_array($existingOptions) || empty($existingOptions)) { + return $dynamicOptions; + } + + $isAssoc = array_keys($existingOptions) !== range(0, count($existingOptions) - 1); + + if ($isAssoc) { + return array_merge($existingOptions, $dynamicOptions); + } + + foreach ($dynamicOptions as $key => $value) { + $existingOptions[] = ['label' => $key, 'value' => $value]; + } + + return $existingOptions; + } + + /** + * options 정규화 [{label, value, unit}] + */ + private function normalizeOptions(?array $in): ?array + { + if (! $in) { + return null; + } + + $isAssoc = array_keys($in) !== range(0, count($in) - 1); + + if ($isAssoc) { + $out = []; + foreach ($in as $k => $v) { + $label = trim((string) $k); + $value = is_scalar($v) ? trim((string) $v) : json_encode($v, JSON_UNESCAPED_UNICODE); + if ($label !== '' || $value !== '') { + $out[] = ['label' => $label, 'value' => $value, 'unit' => '']; + } + } + + return $out ?: null; + } + + $out = []; + foreach ($in as $a) { + if (! is_array($a)) { + continue; + } + $label = trim((string) ($a['label'] ?? '')); + $value = trim((string) ($a['value'] ?? '')); + $unit = trim((string) ($a['unit'] ?? '')); + + if ($label === '' && $value === '') { + continue; + } + + $out[] = ['label' => $label, 'value' => $value, 'unit' => $unit]; + } + + return $out ?: null; + } + + /** + * 동적 필드를 options에 병합하고 정규화 + */ + private function processDynamicOptions(array &$data, string $sourceTable): void + { + $dynamicOptions = $this->extractDynamicOptions($data, $sourceTable); + if (! empty($dynamicOptions)) { + $existingOptions = $data['options'] ?? []; + $data['options'] = $this->mergeOptionsWithDynamic($existingOptions, $dynamicOptions); + } + + if (isset($data['options'])) { + $data['options'] = $this->normalizeOptions($data['options']); + } + } + + /** + * BOM 데이터에서 child_item_id, child_item_type, quantity만 추출 + * + * @param array|null $bomData BOM 데이터 배열 + * @return array|null [{child_item_id, child_item_type, quantity}, ...] + */ + private function extractBomData(?array $bomData): ?array + { + if (empty($bomData)) { + return null; + } + + $extracted = []; + foreach ($bomData as $item) { + if (! is_array($item)) { + continue; + } + + $childItemId = $item['child_item_id'] ?? null; + $childItemType = $item['child_item_type'] ?? $item['ref_type'] ?? 'PRODUCT'; + $quantity = $item['quantity'] ?? null; + + if ($childItemId === null) { + continue; + } + + // child_item_type 정규화 (PRODUCT/MATERIAL) + $childItemType = strtoupper($childItemType); + if (! in_array($childItemType, ['PRODUCT', 'MATERIAL'])) { + $childItemType = 'PRODUCT'; + } + + $extracted[] = [ + 'child_item_id' => (int) $childItemId, + 'child_item_type' => $childItemType, + 'quantity' => $quantity !== null ? (float) $quantity : 1, + ]; + } + + return empty($extracted) ? null : $extracted; + } + + /** + * BOM 데이터 확장 (child_item 상세 정보 포함) + * + * DB에 저장된 [{child_item_id, child_item_type, quantity}] 형태를 + * [{child_item_id, child_item_type, child_item_code, child_item_name, quantity, unit, specification?}] + * 형태로 확장하여 반환 + * + * @param array $bomData BOM 데이터 배열 [{child_item_id, child_item_type, quantity}, ...] + * @param int $tenantId 테넌트 ID + * @return array 확장된 BOM 데이터 + */ + private function expandBomData(array $bomData, int $tenantId): array + { + if (empty($bomData)) { + return []; + } + + // child_item_type별로 ID 분리 + $productIds = []; + $materialIds = []; + + foreach ($bomData as $item) { + $childId = $item['child_item_id'] ?? null; + $childType = strtoupper($item['child_item_type'] ?? 'PRODUCT'); + + if ($childId === null) { + continue; + } + + if ($childType === 'MATERIAL') { + $materialIds[] = $childId; + } else { + $productIds[] = $childId; + } + } + + // Products에서 조회 (FG, PT) + $products = collect([]); + if (! empty($productIds)) { + $products = Product::query() + ->where('tenant_id', $tenantId) + ->whereIn('id', $productIds) + ->get(['id', 'code', 'name', 'unit']) + ->keyBy('id'); + } + + // Materials에서 조회 (SM, RM, CS) + $materials = collect([]); + if (! empty($materialIds)) { + $materials = Material::query() + ->where('tenant_id', $tenantId) + ->whereIn('id', $materialIds) + ->get(['id', 'material_code', 'name', 'unit', 'specification']) + ->keyBy('id'); + } + + // BOM 데이터 확장 + $expanded = []; + foreach ($bomData as $item) { + $childId = $item['child_item_id'] ?? null; + $childType = strtoupper($item['child_item_type'] ?? 'PRODUCT'); + + if ($childId === null) { + continue; + } + + $result = [ + 'child_item_id' => (int) $childId, + 'child_item_type' => $childType, + 'quantity' => $item['quantity'] ?? 1, + ]; + + // child_item_type에 따라 조회 + if ($childType === 'MATERIAL' && isset($materials[$childId])) { + $material = $materials[$childId]; + $result['child_item_code'] = $material->material_code; + $result['child_item_name'] = $material->name; + $result['unit'] = $material->unit; + if ($material->specification) { + $result['specification'] = $material->specification; + } + } elseif ($childType === 'PRODUCT' && isset($products[$childId])) { + $product = $products[$childId]; + $result['child_item_code'] = $product->code; + $result['child_item_name'] = $product->name; + $result['unit'] = $product->unit; + } else { + // 해당하는 품목이 없으면 null 처리 + $result['child_item_code'] = null; + $result['child_item_name'] = null; + $result['unit'] = null; + } + + $expanded[] = $result; + } + + return $expanded; + } + + /** + * 통합 품목 조회 (materials + products UNION) + * + * @param array $filters 필터 조건 (type, search, category_id, page, size) + * @param int $perPage 페이지당 항목 수 + * @param bool $includeDeleted soft delete 포함 여부 + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + */ + public function getItems(array $filters = [], int $perPage = 20, bool $includeDeleted = false) + { + $tenantId = $this->tenantId(); + + // 필터 파라미터 추출 + $types = $filters['type'] ?? ['FG', 'PT', 'SM', 'RM', 'CS']; + $search = trim($filters['search'] ?? $filters['q'] ?? ''); + $categoryId = $filters['category_id'] ?? null; + $isActive = $filters['is_active'] ?? null; // null: 전체, true/1: 활성만, false/0: 비활성만 + + // 타입을 배열로 변환 (문자열인 경우 쉼표로 분리) + if (is_string($types)) { + $types = array_map('trim', explode(',', $types)); + } + + // Product 타입 (FG, PT) + $productTypes = array_intersect(['FG', 'PT'], $types); + // Material 타입 (SM, RM, CS) + $materialTypes = array_intersect(['SM', 'RM', 'CS'], $types); + + // Products 쿼리 (FG, PT 타입만) + $productsQuery = null; + if (! empty($productTypes)) { + $productsQuery = Product::query() + ->where('tenant_id', $tenantId) + ->whereIn('product_type', $productTypes); + + // is_active 필터 적용 (null이면 전체 조회) + if ($isActive !== null) { + $productsQuery->where('is_active', filter_var($isActive, FILTER_VALIDATE_BOOLEAN) ? 1 : 0); + } + + $productsQuery->select([ + 'id', + 'product_type as item_type', + 'code', + 'name', + DB::raw('NULL as specification'), + 'unit', + 'category_id', + 'product_type as type_code', + 'attributes', + 'is_active', + 'created_at', + 'deleted_at', + ]); + + // soft delete 포함 + if ($includeDeleted) { + $productsQuery->withTrashed(); + } + + // 검색 조건 + if ($search !== '') { + $productsQuery->where(function ($q) use ($search) { + $q->where('name', 'like', "%{$search}%") + ->orWhere('code', 'like', "%{$search}%"); + }); + } + + // 카테고리 필터 + if ($categoryId) { + $productsQuery->where('category_id', (int) $categoryId); + } + } + + // Materials 쿼리 (SM, RM, CS 타입) + $materialsQuery = null; + if (! empty($materialTypes)) { + $materialsQuery = Material::query() + ->where('tenant_id', $tenantId) + ->whereIn('material_type', $materialTypes); + + // is_active 필터 적용 (null이면 전체 조회) + if ($isActive !== null) { + $materialsQuery->where('is_active', filter_var($isActive, FILTER_VALIDATE_BOOLEAN) ? 1 : 0); + } + + $materialsQuery->select([ + 'id', + 'material_type as item_type', + 'material_code as code', + 'name', + 'specification', + 'unit', + 'category_id', + 'material_type as type_code', + 'attributes', + 'is_active', + 'created_at', + 'deleted_at', + ]); + + // soft delete 포함 + if ($includeDeleted) { + $materialsQuery->withTrashed(); + } + + // 검색 조건 + if ($search !== '') { + $materialsQuery->where(function ($q) use ($search) { + $q->where('name', 'like', "%{$search}%") + ->orWhere('item_name', 'like', "%{$search}%") + ->orWhere('material_code', 'like', "%{$search}%") + ->orWhere('search_tag', 'like', "%{$search}%"); + }); + } + + // 카테고리 필터 + if ($categoryId) { + $materialsQuery->where('category_id', (int) $categoryId); + } + } + + // 각 쿼리 실행 후 merge (UNION 바인딩 문제 방지) + $items = collect([]); + + if ($productsQuery) { + $products = $productsQuery->get(); + $items = $items->merge($products); + } + + if ($materialsQuery) { + $materials = $materialsQuery->get(); + $items = $items->merge($materials); + } + + // 정렬 (created_at 기준 내림차순) + $items = $items->sortByDesc('created_at')->values(); + + // attributes 플랫 전개 + $items = $items->map(function ($item) { + $data = $item->toArray(); + $attributes = $data['attributes'] ?? []; + if (is_string($attributes)) { + $attributes = json_decode($attributes, true) ?? []; + } + unset($data['attributes']); + + return array_merge($data, $attributes); + }); + + // 페이지네이션 처리 + $page = request()->input('page', 1); + $offset = ($page - 1) * $perPage; + $total = $items->count(); + + $paginatedItems = $items->slice($offset, $perPage)->values(); + + return new \Illuminate\Pagination\LengthAwarePaginator( + $paginatedItems, + $total, + $perPage, + $page, + ['path' => request()->url(), 'query' => request()->query()] + ); + } + + /** + * 단일 품목 조회 + * + * @param int $id 품목 ID + * @param string $itemType 품목 유형 코드 (FG/PT/SM/RM/CS) + * @param bool $includePrice 가격 정보 포함 여부 + * @param int|null $clientId 고객 ID (가격 조회 시) + * @param string|null $priceDate 기준일 (가격 조회 시) + * @return array 품목 데이터 (item_type, prices 포함) + */ + public function getItem( + int $id, + string $itemType = 'FG', + bool $includePrice = false, + ?int $clientId = null, + ?string $priceDate = null + ): array { + $tenantId = $this->tenantId(); + $itemType = strtoupper($itemType); + + // item_type으로 source_table 결정 + if (ItemTypeHelper::isMaterial($itemType, $tenantId)) { + $material = Material::query() + ->with('category:id,name') + ->where('tenant_id', $tenantId) + ->find($id); + + if (! $material) { + throw new NotFoundHttpException(__('error.not_found')); + } + + $data = $this->flattenAttributes($material->toArray()); + $data['item_type'] = $itemType; + $data['code'] = $material->material_code; + $data['type_code'] = $material->material_type; + + // 가격 정보 추가 + if ($includePrice) { + $data['prices'] = $this->fetchPrices('MATERIAL', $id, $clientId, $priceDate); + } + + // 파일 정보 추가 + $data['files'] = $this->getItemFiles($id, $tenantId); + + return $data; + } + + // Product (FG, PT) + $product = Product::query() + ->with('category:id,name') + ->where('tenant_id', $tenantId) + ->find($id); + + if (! $product) { + throw new NotFoundHttpException(__('error.not_found')); + } + + $data = $this->flattenAttributes($product->toArray()); + $data['item_type'] = $itemType; + $data['type_code'] = $product->product_type; + + // BOM 데이터 확장 (child_item 상세 정보 포함) + if (! empty($data['bom'])) { + $data['bom'] = $this->expandBomData($data['bom'], $tenantId); + } + + // 가격 정보 추가 + if ($includePrice) { + $data['prices'] = $this->fetchPrices('PRODUCT', $id, $clientId, $priceDate); + } + + // 파일 정보 추가 + $data['files'] = $this->getItemFiles($id, $tenantId); + + return $data; + } + + /** + * attributes/options JSON 필드를 최상위로 플랫 전개 + */ + private function flattenAttributes(array $data): array + { + // attributes 플랫 전개 + $attributes = $data['attributes'] ?? []; + if (is_string($attributes)) { + $attributes = json_decode($attributes, true) ?? []; + } + unset($data['attributes']); + + // options 플랫 전개 ([{label, value, unit}] 형태 → {label: value} 형태로 변환) + $options = $data['options'] ?? []; + if (is_string($options)) { + $options = json_decode($options, true) ?? []; + } + $flatOptions = []; + if (is_array($options)) { + foreach ($options as $opt) { + if (is_array($opt) && isset($opt['label'])) { + $flatOptions[$opt['label']] = $opt['value'] ?? ''; + } + } + } + // options는 원본 유지 (프론트에서 필요할 수 있음) + + return array_merge($data, $attributes, $flatOptions); + } + + /** + * 품목의 판매가/매입가 조회 + * + * @param string $itemType 'PRODUCT' | 'MATERIAL' + * @param int $itemId 품목 ID + * @param int|null $clientId 고객 ID + * @param string|null $priceDate 기준일 + * @return array ['sale' => array, 'purchase' => array] + */ + private function fetchPrices(string $itemType, int $itemId, ?int $clientId, ?string $priceDate): array + { + // PricingService DI가 없으므로 직접 생성 + $pricingService = app(\App\Services\Pricing\PricingService::class); + + $salePrice = $pricingService->getPriceByType($itemType, $itemId, 'SALE', $clientId, $priceDate); + $purchasePrice = $pricingService->getPriceByType($itemType, $itemId, 'PURCHASE', $clientId, $priceDate); + + return [ + 'sale' => $salePrice, + 'purchase' => $purchasePrice, + ]; + } + + /** + * 품목 생성 (타입에 따라 Products 또는 Materials 테이블에 저장) + * + * - FG, PT → Products 테이블 + * - SM, RM, CS → Materials 테이블 + * + * @param array $data 검증된 데이터 + */ + public function createItem(array $data): Product|Material + { + $tenantId = $this->tenantId(); + $userId = $this->apiUserId(); + $itemType = strtoupper($data['product_type'] ?? 'FG'); + + // Materials 타입 (SM, RM, CS) + if (in_array($itemType, ['SM', 'RM', 'CS'])) { + return $this->createMaterial($data, $tenantId, $userId, $itemType); + } + + // Products 타입 (FG, PT) - 기본값 + return $this->createProduct($data, $tenantId, $userId); + } + + /** + * Product 생성 (FG, PT) + */ + private function createProduct(array $data, int $tenantId, int $userId): Product + { + // 품목 코드 중복 체크 + $code = $data['code'] ?? ''; + $existingProduct = Product::withTrashed() + ->where('tenant_id', $tenantId) + ->where('code', $code) + ->first(); + + if ($existingProduct) { + throw new DuplicateCodeException($code, $existingProduct->id); + } + + // 동적 필드를 options에 병합 + $this->processDynamicOptions($data, 'products'); + + // BOM 데이터 처리 (child_item_id, quantity만 추출) + $bomData = $this->extractBomData($data['bom'] ?? null); + + $payload = $data; + $payload['tenant_id'] = $tenantId; + $payload['created_by'] = $userId; + $payload['is_active'] = $payload['is_active'] ?? true; + $payload['is_sellable'] = $payload['is_sellable'] ?? true; + $payload['is_purchasable'] = $payload['is_purchasable'] ?? false; + $payload['is_producible'] = $payload['is_producible'] ?? false; + $payload['bom'] = $bomData; + + return Product::create($payload); + } + + /** + * Material 생성 (SM, RM, CS) + */ + private function createMaterial(array $data, int $tenantId, int $userId, string $materialType): Material + { + // 품목 코드 중복 체크 + $code = $data['code'] ?? $data['material_code'] ?? ''; + $existingMaterial = Material::withTrashed() + ->where('tenant_id', $tenantId) + ->where('material_code', $code) + ->first(); + + if ($existingMaterial) { + throw new DuplicateCodeException($code, $existingMaterial->id); + } + + // 동적 필드를 options에 병합 + $this->processDynamicOptions($data, 'materials'); + + $payload = [ + 'tenant_id' => $tenantId, + 'created_by' => $userId, + 'material_type' => $materialType, + 'material_code' => $code, + 'name' => $data['name'], + 'unit' => $data['unit'], + 'category_id' => $data['category_id'] ?? null, + 'item_name' => $data['item_name'] ?? $data['name'], + 'specification' => $data['specification'] ?? $data['description'] ?? null, + 'is_inspection' => $data['is_inspection'] ?? 'N', + 'search_tag' => $data['search_tag'] ?? null, + 'remarks' => $data['remarks'] ?? null, + 'attributes' => $data['attributes'] ?? null, + 'options' => $data['options'] ?? null, + 'is_active' => $data['is_active'] ?? true, + ]; + + return Material::create($payload); + } + + /** + * 품목 수정 (Product/Material 통합) + * + * @param int $id 품목 ID + * @param array $data 검증된 데이터 (item_type 필수) + */ + public function updateItem(int $id, array $data): Product|Material + { + $tenantId = $this->tenantId(); + $itemType = strtoupper($data['item_type'] ?? 'FG'); + + if (ItemTypeHelper::isMaterial($itemType, $tenantId)) { + return $this->updateMaterial($id, $data); + } + + return $this->updateProduct($id, $data); + } + + /** + * Product 수정 (FG, PT) + */ + private function updateProduct(int $id, array $data): Product + { + $tenantId = $this->tenantId(); + $userId = $this->apiUserId(); + + $product = Product::query() + ->where('tenant_id', $tenantId) + ->find($id); + + if (! $product) { + throw new NotFoundHttpException(__('error.not_found')); + } + + // 코드 변경 시 중복 체크 + if (isset($data['code']) && $data['code'] !== $product->code) { + $existingProduct = Product::query() + ->where('tenant_id', $tenantId) + ->where('code', $data['code']) + ->where('id', '!=', $product->id) + ->first(); + + if ($existingProduct) { + throw new DuplicateCodeException($data['code'], $existingProduct->id); + } + } + + // 동적 필드를 options에 병합 + $this->processDynamicOptions($data, 'products'); + + // BOM 데이터 처리 (bom 키가 있을 때만) + if (array_key_exists('bom', $data)) { + $data['bom'] = $this->extractBomData($data['bom']); + } + + // item_type은 DB 필드가 아니므로 제거 + unset($data['item_type']); + $data['updated_by'] = $userId; + $product->update($data); + + return $product->refresh(); + } + + /** + * Material 수정 (SM, RM, CS) + */ + private function updateMaterial(int $id, array $data): Material + { + $tenantId = $this->tenantId(); + $userId = $this->apiUserId(); + + $material = Material::query() + ->where('tenant_id', $tenantId) + ->find($id); + + if (! $material) { + throw new NotFoundHttpException(__('error.not_found')); + } + + // 코드 변경 시 중복 체크 + $newCode = $data['material_code'] ?? $data['code'] ?? null; + if ($newCode && $newCode !== $material->material_code) { + $existingMaterial = Material::query() + ->where('tenant_id', $tenantId) + ->where('material_code', $newCode) + ->where('id', '!=', $material->id) + ->first(); + + if ($existingMaterial) { + throw new DuplicateCodeException($newCode, $existingMaterial->id); + } + $data['material_code'] = $newCode; + } + + // 동적 필드를 options에 병합 + $this->processDynamicOptions($data, 'materials'); + + // item_type, code는 DB 필드가 아니므로 제거 + unset($data['item_type'], $data['code']); + $data['updated_by'] = $userId; + $material->update($data); + + return $material->refresh(); + } + + /** + * 품목 삭제 (Product/Material 통합, Force Delete) + * + * - 이미 삭제된 품목은 404 반환 + * - 다른 테이블에서 사용 중이면 삭제 불가 + * - 사용 안함 → Force Delete (영구 삭제) + * + * @param int $id 품목 ID + * @param string $itemType 품목 유형 코드 (FG/PT/SM/RM/CS) + */ + public function deleteItem(int $id, string $itemType = 'FG'): void + { + $tenantId = $this->tenantId(); + $itemType = strtoupper($itemType); + + if (ItemTypeHelper::isMaterial($itemType, $tenantId)) { + $this->deleteMaterial($id); + + return; + } + + $this->deleteProduct($id); + } + + /** + * Product 삭제 (FG, PT) - Force Delete + * + * - 사용 중이면 삭제 불가 (에러) + * - 사용 안함 → 영구 삭제 + */ + private function deleteProduct(int $id): void + { + $tenantId = $this->tenantId(); + + $product = Product::query() + ->where('tenant_id', $tenantId) + ->find($id); + + if (! $product) { + throw new NotFoundHttpException(__('error.item.not_found')); + } + + // 사용 여부 종합 체크 + $usageResult = $this->checkProductUsage($tenantId, $id); + if ($usageResult['is_used']) { + $usageMessage = $this->formatUsageMessage($usageResult['usage']); + throw new BadRequestHttpException(__('error.item.in_use', ['usage' => $usageMessage])); + } + + // 사용 안함 → Force Delete + $product->forceDelete(); + } + + /** + * Material 삭제 (SM, RM, CS) - Force Delete + * + * - 사용 중이면 삭제 불가 (에러) + * - 사용 안함 → 영구 삭제 + */ + private function deleteMaterial(int $id): void + { + $tenantId = $this->tenantId(); + + $material = Material::query() + ->where('tenant_id', $tenantId) + ->find($id); + + if (! $material) { + throw new NotFoundHttpException(__('error.item.not_found')); + } + + // 사용 여부 종합 체크 + $usageResult = $this->checkMaterialUsage($tenantId, $id); + if ($usageResult['is_used']) { + $usageMessage = $this->formatUsageMessage($usageResult['usage']); + throw new BadRequestHttpException(__('error.item.in_use', ['usage' => $usageMessage])); + } + + // 사용 안함 → Force Delete + $material->forceDelete(); + } + + /** + * Product 사용 여부 종합 체크 (모든 참조 테이블) + * + * @param int $tenantId 테넌트 ID + * @param int $productId 제품 ID + * @return array ['is_used' => bool, 'usage' => ['table' => count, ...]] + */ + private function checkProductUsage(int $tenantId, int $productId): array + { + $usage = []; + + // 1. BOM 구성품으로 사용 (product_components.ref_type=PRODUCT) + $bomComponentCount = \App\Models\Products\ProductComponent::query() + ->where('tenant_id', $tenantId) + ->where('ref_type', 'PRODUCT') + ->where('ref_id', $productId) + ->count(); + if ($bomComponentCount > 0) { + $usage['bom_components'] = $bomComponentCount; + } + + // 2. BOM 상위품목으로 사용 (product_components.parent_product_id) + $bomParentCount = \App\Models\Products\ProductComponent::query() + ->where('tenant_id', $tenantId) + ->where('parent_product_id', $productId) + ->count(); + if ($bomParentCount > 0) { + $usage['bom_parent'] = $bomParentCount; + } + + // 3. BOM 템플릿 항목 (bom_template_items.ref_type=PRODUCT) + $bomTemplateCount = \App\Models\Design\BomTemplateItem::query() + ->where('tenant_id', $tenantId) + ->where('ref_type', 'PRODUCT') + ->where('ref_id', $productId) + ->count(); + if ($bomTemplateCount > 0) { + $usage['bom_templates'] = $bomTemplateCount; + } + + // 4. 주문 (orders.product_id) + $orderCount = \App\Models\Orders\Order::query() + ->where('tenant_id', $tenantId) + ->where('product_id', $productId) + ->count(); + if ($orderCount > 0) { + $usage['orders'] = $orderCount; + } + + // 5. 주문 항목 (order_items.product_id) + $orderItemCount = \App\Models\Orders\OrderItem::query() + ->where('tenant_id', $tenantId) + ->where('product_id', $productId) + ->count(); + if ($orderItemCount > 0) { + $usage['order_items'] = $orderItemCount; + } + + // 6. 견적 (quotes.product_id) + $quoteCount = \App\Models\Quote\Quote::query() + ->where('tenant_id', $tenantId) + ->where('product_id', $productId) + ->count(); + if ($quoteCount > 0) { + $usage['quotes'] = $quoteCount; + } + + return [ + 'is_used' => ! empty($usage), + 'usage' => $usage, + ]; + } + + /** + * Material 사용 여부 종합 체크 (모든 참조 테이블) + * + * @param int $tenantId 테넌트 ID + * @param int $materialId 자재 ID + * @return array ['is_used' => bool, 'usage' => ['table' => count, ...]] + */ + private function checkMaterialUsage(int $tenantId, int $materialId): array + { + $usage = []; + + // 1. BOM 구성품으로 사용 (product_components.ref_type=MATERIAL) + $bomComponentCount = \App\Models\Products\ProductComponent::query() + ->where('tenant_id', $tenantId) + ->where('ref_type', 'MATERIAL') + ->where('ref_id', $materialId) + ->count(); + if ($bomComponentCount > 0) { + $usage['bom_components'] = $bomComponentCount; + } + + // 2. BOM 템플릿 항목 (bom_template_items.ref_type=MATERIAL) + $bomTemplateCount = \App\Models\Design\BomTemplateItem::query() + ->where('tenant_id', $tenantId) + ->where('ref_type', 'MATERIAL') + ->where('ref_id', $materialId) + ->count(); + if ($bomTemplateCount > 0) { + $usage['bom_templates'] = $bomTemplateCount; + } + + // 3. 자재 입고 (material_receipts.material_id) + $receiptCount = \App\Models\Materials\MaterialReceipt::query() + ->where('tenant_id', $tenantId) + ->where('material_id', $materialId) + ->count(); + if ($receiptCount > 0) { + $usage['receipts'] = $receiptCount; + } + + // 4. LOT (lots.material_id) + $lotCount = \App\Models\Qualitys\Lot::query() + ->where('tenant_id', $tenantId) + ->where('material_id', $materialId) + ->count(); + if ($lotCount > 0) { + $usage['lots'] = $lotCount; + } + + return [ + 'is_used' => ! empty($usage), + 'usage' => $usage, + ]; + } + + /** + * 사용처 정보를 한글 메시지로 변환 + */ + private function formatUsageMessage(array $usage): string + { + $labels = [ + 'bom_components' => 'BOM 구성품', + 'bom_parent' => 'BOM 상위품목', + 'bom_templates' => 'BOM 템플릿', + 'orders' => '주문', + 'order_items' => '주문 항목', + 'quotes' => '견적', + 'receipts' => '입고', + 'lots' => 'LOT', + ]; + + $parts = []; + foreach ($usage as $key => $count) { + $label = $labels[$key] ?? $key; + $parts[] = "{$label} {$count}건"; + } + + return implode(', ', $parts); + } + + /** + * 품목 일괄 삭제 (Product/Material 통합, Force Delete) + * + * - 다른 테이블에서 사용 중인 품목은 삭제 불가 + * - 사용 안함 → Force Delete (영구 삭제) + * + * @param array $ids 품목 ID 배열 + * @param string $itemType 품목 유형 코드 (FG/PT/SM/RM/CS) + */ + public function batchDeleteItems(array $ids, string $itemType = 'FG'): void + { + $tenantId = $this->tenantId(); + $itemType = strtoupper($itemType); + + if (ItemTypeHelper::isMaterial($itemType, $tenantId)) { + $this->batchDeleteMaterials($ids); + + return; + } + + $this->batchDeleteProducts($ids); + } + + /** + * Product 일괄 삭제 (FG, PT) - Force Delete + * + * - 사용 중인 품목이 있으면 전체 삭제 실패 + * - 모두 사용 안함 → 영구 삭제 + */ + private function batchDeleteProducts(array $ids): void + { + $tenantId = $this->tenantId(); + + $products = Product::query() + ->where('tenant_id', $tenantId) + ->whereIn('id', $ids) + ->get(); + + if ($products->isEmpty()) { + throw new NotFoundHttpException(__('error.item.not_found')); + } + + // 사용 중인 품목 체크 (하나라도 사용 중이면 전체 실패) + $inUseItems = []; + foreach ($products as $product) { + $usageResult = $this->checkProductUsage($tenantId, $product->id); + if ($usageResult['is_used']) { + $inUseItems[] = [ + 'id' => $product->id, + 'code' => $product->code, + 'usage' => $usageResult['usage'], + ]; + } + } + + if (! empty($inUseItems)) { + $codes = array_column($inUseItems, 'code'); + throw new BadRequestHttpException(__('error.item.batch_in_use', [ + 'codes' => implode(', ', $codes), + 'count' => count($inUseItems), + ])); + } + + // 모두 사용 안함 → Force Delete + foreach ($products as $product) { + $product->forceDelete(); + } + } + + /** + * Material 일괄 삭제 (SM, RM, CS) - Force Delete + * + * - 사용 중인 자재가 있으면 전체 삭제 실패 + * - 모두 사용 안함 → 영구 삭제 + */ + private function batchDeleteMaterials(array $ids): void + { + $tenantId = $this->tenantId(); + + $materials = Material::query() + ->where('tenant_id', $tenantId) + ->whereIn('id', $ids) + ->get(); + + if ($materials->isEmpty()) { + throw new NotFoundHttpException(__('error.item.not_found')); + } + + // 사용 중인 자재 체크 (하나라도 사용 중이면 전체 실패) + $inUseItems = []; + foreach ($materials as $material) { + $usageResult = $this->checkMaterialUsage($tenantId, $material->id); + if ($usageResult['is_used']) { + $inUseItems[] = [ + 'id' => $material->id, + 'code' => $material->material_code, + 'usage' => $usageResult['usage'], + ]; + } + } + + if (! empty($inUseItems)) { + $codes = array_column($inUseItems, 'code'); + throw new BadRequestHttpException(__('error.item.batch_in_use', [ + 'codes' => implode(', ', $codes), + 'count' => count($inUseItems), + ])); + } + + // 모두 사용 안함 → Force Delete + foreach ($materials as $material) { + $material->forceDelete(); + } + } + + /** + * 품목의 파일 목록 조회 (field_key별 그룹핑) + * + * @param int $itemId 품목 ID + * @param int $tenantId 테넌트 ID + * @return array field_key별로 그룹핑된 파일 목록 + */ + private function getItemFiles(int $itemId, int $tenantId): array + { + $files = File::query() + ->where('tenant_id', $tenantId) + ->where('document_type', '1') // ITEM_GROUP_ID + ->where('document_id', $itemId) + ->whereNull('deleted_at') + ->orderBy('created_at', 'desc') + ->get(); + + if ($files->isEmpty()) { + return []; + } + + return $files->groupBy('field_key')->map(function ($group) { + return $group->map(fn ($file) => [ + 'id' => $file->id, + 'file_name' => $file->display_name ?? $file->file_name, + 'file_path' => $file->file_path, + ])->values()->toArray(); + })->toArray(); + } + + /** + * 품목 상세 조회 (code 기반, BOM 포함 옵션) + * + * Product 먼저 조회 → 없으면 Material 조회 + * + * @param string $code 품목 코드 + * @param bool $includeBom BOM 포함 여부 + * @return array 품목 데이터 (attributes 플랫 전개) + */ + public function getItemByCode(string $code, bool $includeBom = false): array + { + $tenantId = $this->tenantId(); + + // 1. Product에서 먼저 조회 + $query = Product::query() + ->with('category:id,name') + ->where('tenant_id', $tenantId) + ->where('code', $code); + + if ($includeBom) { + $query->with('componentLines.childProduct:id,code,name,unit'); + } + + $product = $query->first(); + + if ($product) { + $data = $this->flattenAttributes($product->toArray()); + $data['item_type'] = $product->product_type; + $data['type_code'] = $product->product_type; + + return $data; + } + + // 2. Material에서 조회 + $material = Material::query() + ->with('category:id,name') + ->where('tenant_id', $tenantId) + ->where('material_code', $code) + ->first(); + + if ($material) { + $data = $this->flattenAttributes($material->toArray()); + $data['item_type'] = $material->material_type; + $data['code'] = $material->material_code; + $data['type_code'] = $material->material_type; + + return $data; + } + + throw new NotFoundHttpException(__('error.not_found')); + } +} diff --git a/app/Services/ItemsService.php:Zone.Identifier b/app/Services/ItemsService.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xtenantId(); + + // 1. SystemFields에서 materials 테이블 고정 컬럼 + $systemFields = SystemFields::getReservedKeys(SystemFields::SOURCE_TABLE_MATERIALS); + + // 2. ItemField에서 storage_type='column'인 필드의 field_key 조회 + $columnFields = ItemField::where('tenant_id', $tenantId) + ->where('source_table', 'materials') + ->where('storage_type', 'column') + ->whereNotNull('field_key') + ->pluck('field_key') + ->toArray(); + + // 3. 추가적인 API 전용 필드 (DB 컬럼이 아니지만 API에서 사용하는 필드) + $apiFields = ['item_type', 'type_code', 'bom']; + + return array_unique(array_merge($systemFields, $columnFields, $apiFields)); + } + + /** + * 정의된 필드 외의 동적 필드를 options로 추출 + */ + private function extractDynamicOptions(array $params): array + { + $knownFields = $this->getKnownFields(); + + $dynamicOptions = []; + foreach ($params as $key => $value) { + if (! in_array($key, $knownFields) && $value !== null && $value !== '') { + $dynamicOptions[$key] = $value; + } + } + + return $dynamicOptions; + } + + /** + * 기존 options 배열과 동적 필드를 병합 + * - 기존 options가 [{label, value}] 배열이면 동적 필드를 배열 항목으로 추가 + * - 기존 options가 {key: value} 맵이면 동적 필드를 맵에 병합 + */ + private function mergeOptionsWithDynamic($existingOptions, array $dynamicOptions): array + { + if (! is_array($existingOptions) || empty($existingOptions)) { + // 기존 options가 없으면 동적 필드만 반환 + return $dynamicOptions; + } + + // 기존 options가 연관 배열(맵)인지 판별 + $isAssoc = array_keys($existingOptions) !== range(0, count($existingOptions) - 1); + + if ($isAssoc) { + // 맵 형태면 단순 병합 + return array_merge($existingOptions, $dynamicOptions); + } + + // 배열 형태 [{label, value}]면 동적 필드를 배열 항목으로 추가 + foreach ($dynamicOptions as $key => $value) { + $existingOptions[] = ['label' => $key, 'value' => $value]; + } + + return $existingOptions; + } + + /** 공통 검증 헬퍼 */ + protected function v(array $input, array $rules) + { + $v = Validator::make($input, $rules); + if ($v->fails()) { + return ['error' => $v->errors()->first(), 'code' => 422]; + } + + return $v->validated(); + } + + /** 목록 */ + public function getMaterials(array $params) + { + $tenantId = $this->tenantId(); + + $p = $this->v($params, [ + 'q' => 'nullable|string|max:100', + 'category' => 'nullable|integer|min:1', + 'page' => 'nullable|integer|min:1', + 'per_page' => 'nullable|integer|min:1|max:200', + ]); + if (isset($p['error'])) { + return $p; + } + + $q = Material::query() + ->where('tenant_id', $tenantId); // SoftDeletes가 있으면 기본적으로 deleted_at IS NULL + + if (! empty($p['category'])) { + $q->where('category_id', (int) $p['category']); + } + if (! empty($p['q'])) { + $kw = '%'.$p['q'].'%'; + $q->where(function ($w) use ($kw) { + $w->where('item_name', 'like', $kw) + ->orWhere('name', 'like', $kw) + ->orWhere('material_code', 'like', $kw) + ->orWhere('search_tag', 'like', $kw); + }); + } + + $q->orderBy('id'); + + $perPage = $p['per_page'] ?? 20; + $page = $p['page'] ?? null; + + return $q->paginate($perPage, ['*'], 'page', $page); + } + + /** 단건 조회 */ + public function getMaterial(int $id) + { + $tenantId = $this->tenantId(); + + /** @var Material|null $row */ + $row = Material::query() + ->where('tenant_id', $tenantId) + ->find($id); + + if (! $row) { + return ['error' => '자재를 찾을 수 없습니다.', 'code' => 404]; + } + + // 모델에서 casts가 없을 수 있으니 안전하게 배열화 + $row->attributes = is_array($row->attributes) ? $row->attributes : ($row->attributes ? json_decode($row->attributes, true) : null); + $row->options = is_array($row->options) ? $row->options : ($row->options ? json_decode($row->options, true) : null); + + return $row; + } + + /** 등록 */ + public function setMaterial(array $params) + { + $tenantId = $this->tenantId(); + $userId = $this->apiUserId(); + + // 동적 필드를 options에 병합 + $dynamicOptions = $this->extractDynamicOptions($params); + if (! empty($dynamicOptions)) { + $existingOptions = $params['options'] ?? []; + $params['options'] = $this->mergeOptionsWithDynamic($existingOptions, $dynamicOptions); + } + + $p = $this->v($params, [ + 'category_id' => 'nullable|integer|min:1', + 'name' => 'required|string|max:100', + 'unit' => 'required|string|max:10', + 'is_inspection' => 'nullable|in:Y,N', + 'search_tag' => 'nullable|string', + 'remarks' => 'nullable|string', + 'attributes' => 'nullable|array', // [{label,value,unit}] 또는 map + 'options' => 'nullable|array', // [{label,value,unit}] 또는 map + 'material_code' => 'nullable|string|max:50', + 'specification' => 'nullable|string|max:100', + ]); + if (isset($p['error'])) { + return $p; + } + + // material_code 중복 체크 (삭제된 레코드 포함 - DB unique 제약은 deleted_at 무시) + if (! empty($p['material_code'])) { + $duplicate = Material::withTrashed() + ->where('tenant_id', $tenantId) + ->where('material_code', $p['material_code']) + ->first(['id', 'name', 'deleted_at']); + + if ($duplicate) { + if ($duplicate->deleted_at) { + return [ + 'error' => "자재코드 '{$p['material_code']}'가 삭제된 자재에서 사용 중입니다. 해당 자재를 복구하거나 완전 삭제 후 다시 시도하세요.", + 'code' => 422, + 'deleted_material_id' => $duplicate->id, + ]; + } + + return ['error' => "자재코드 '{$p['material_code']}'가 이미 존재합니다.", 'code' => 422]; + } + } + + // 기존 normalizeAttributes 사용(그대로), options는 새 normalizeOptions 사용 + $attributes = $this->normalizeAttributes($p['attributes'] ?? null); + $options = $this->normalizeOptions($p['options'] ?? null); + + $itemName = $this->buildItemName($p['name'], $attributes); + $specText = $p['specification'] ?? $this->buildSpecText($attributes); + + $m = new Material; + $m->tenant_id = $tenantId; + $m->category_id = $p['category_id'] ?? null; + $m->name = $p['name']; + $m->item_name = $itemName; + $m->specification = $specText; + $m->material_code = $p['material_code'] ?? null; + $m->unit = $p['unit']; + $m->is_inspection = $p['is_inspection'] ?? 'N'; + $m->search_tag = $p['search_tag'] ?? null; + $m->remarks = $p['remarks'] ?? null; + $m->attributes = $attributes ?? null; + $m->options = $options ?? null; + $m->created_by = $userId ?? 0; + $m->updated_by = $userId ?? null; + $m->save(); + + return $this->getMaterial($m->id); + } + + /** 수정 */ + public function updateMaterial(int $id, array $params = []) + { + $tenantId = $this->tenantId(); + $userId = $this->apiUserId(); + + /** @var Material|null $exists */ + $exists = Material::query()->where('tenant_id', $tenantId)->find($id); + if (! $exists) { + return ['error' => '자재를 찾을 수 없습니다.', 'code' => 404]; + } + + // 동적 필드를 options에 병합 + $dynamicOptions = $this->extractDynamicOptions($params); + if (! empty($dynamicOptions)) { + $existingOptions = $params['options'] ?? []; + $params['options'] = $this->mergeOptionsWithDynamic($existingOptions, $dynamicOptions); + } + + $p = $this->v($params, [ + 'category_id' => 'nullable|integer|min:1', + 'name' => 'nullable|string|max:100', + 'unit' => 'nullable|string|max:10', + 'is_inspection' => 'nullable|in:Y,N', + 'search_tag' => 'nullable|string', + 'remarks' => 'nullable|string', + 'attributes' => 'nullable|array', // [{label,value,unit}] 또는 map + 'options' => 'nullable|array', // [{label,value,unit}] 또는 map + 'material_code' => 'nullable|string|max:50', + 'specification' => 'nullable|string|max:100', + ]); + if (isset($p['error'])) { + return $p; + } + + // material_code 중복 체크 (삭제된 레코드 포함 - DB unique 제약은 deleted_at 무시) + $finalMaterialCode = $p['material_code'] ?? $exists->material_code; + if (! empty($finalMaterialCode)) { + $duplicate = Material::withTrashed() + ->where('tenant_id', $tenantId) + ->where('material_code', $finalMaterialCode) + ->where('id', '!=', $id) + ->first(['id', 'name', 'deleted_at']); + + if ($duplicate) { + if ($duplicate->deleted_at) { + return [ + 'error' => "자재코드 '{$finalMaterialCode}'가 삭제된 자재에서 사용 중입니다. 해당 자재를 복구하거나 완전 삭제 후 다시 시도하세요.", + 'code' => 422, + 'deleted_material_id' => $duplicate->id, + ]; + } + + return ['error' => "자재코드 '{$finalMaterialCode}'가 이미 존재합니다.", 'code' => 422]; + } + } + + $currentAttrs = is_array($exists->attributes) ? $exists->attributes + : ($exists->attributes ? json_decode($exists->attributes, true) : null); + $currentOpts = is_array($exists->options) ? $exists->options + : ($exists->options ? json_decode($exists->options, true) : null); + + // 변경 점만 정규화 + $attrs = array_key_exists('attributes', $p) + ? $this->normalizeAttributes($p['attributes']) + : $currentAttrs; + $opts = array_key_exists('options', $p) + ? $this->normalizeOptions($p['options']) + : $currentOpts; + + $baseName = array_key_exists('name', $p) ? ($p['name'] ?? $exists->name) : $exists->name; + + $exists->category_id = $p['category_id'] ?? $exists->category_id; + $exists->name = $baseName; + $exists->item_name = $this->buildItemName($baseName, $attrs); + $exists->specification = array_key_exists('specification', $p) + ? ($p['specification'] ?? null) + : ($exists->specification ?: $this->buildSpecText($attrs)); + $exists->material_code = $p['material_code'] ?? $exists->material_code; + $exists->unit = $p['unit'] ?? $exists->unit; + $exists->is_inspection = $p['is_inspection'] ?? $exists->is_inspection; + $exists->search_tag = $p['search_tag'] ?? $exists->search_tag; + $exists->remarks = $p['remarks'] ?? $exists->remarks; + + if (array_key_exists('attributes', $p)) { + $exists->attributes = $attrs; + } + if (array_key_exists('options', $p)) { + $exists->options = $opts; + } + + $exists->updated_by = $userId ?? $exists->updated_by; + $exists->save(); + + return $this->getMaterial($exists->id); + } + + /** 삭제(소프트) */ + public function destroyMaterial(int $id) + { + $tenantId = $this->tenantId(); + + /** @var Material|null $row */ + $row = Material::query() + ->where('tenant_id', $tenantId) + ->find($id); + + if (! $row) { + return ['error' => '자재를 찾을 수 없습니다.', 'code' => 404]; + } + + // 사용 중인 자재 삭제 방지 + $usageCheck = $this->checkMaterialUsage($id, $tenantId); + if ($usageCheck['in_use']) { + return [ + 'error' => '사용 중인 자재는 삭제할 수 없습니다.', + 'code' => 422, + 'usage' => $usageCheck['details'], + ]; + } + + $row->delete(); + + return ['id' => $id, 'deleted_at' => now()->toDateTimeString()]; + } + + /** + * 자재 사용 여부 체크 + * - material_receipts: 입고 내역 + * - lots: 로트 관리 + * - product_components: BOM 구성품 (ref_type='MATERIAL') + */ + private function checkMaterialUsage(int $materialId, int $tenantId): array + { + $details = []; + + // 1. 입고 내역 체크 + $receiptCount = \App\Models\Materials\MaterialReceipt::where('tenant_id', $tenantId) + ->where('material_id', $materialId) + ->count(); + if ($receiptCount > 0) { + $details['receipts'] = $receiptCount; + } + + // 2. 로트 체크 + $lotCount = \App\Models\Qualitys\Lot::where('tenant_id', $tenantId) + ->where('material_id', $materialId) + ->count(); + if ($lotCount > 0) { + $details['lots'] = $lotCount; + } + + // 3. BOM 구성품 체크 (ref_type='MATERIAL', ref_id=material_id) + $bomCount = \App\Models\Products\ProductComponent::where('tenant_id', $tenantId) + ->where('ref_type', 'MATERIAL') + ->where('ref_id', $materialId) + ->count(); + if ($bomCount > 0) { + $details['bom_components'] = $bomCount; + } + + return [ + 'in_use' => ! empty($details), + 'details' => $details, + ]; + } + + /* ------------------------- + 헬퍼: 규격/품목명 빌더 + attributes 예시: + [ + {"label":"두께","value":"10","unit":"T"}, + {"label":"길이","value":"150","unit":"CM"} + ] + → item_name: "철판 10T 150CM" + → specification: "두께 10T, 길이 150CM" + ------------------------- */ + + private function normalizeAttributes(?array $attrs): ?array + { + if (! $attrs) { + return null; + } + + $out = []; + foreach ($attrs as $a) { + if (! is_array($a)) { + continue; + } + $label = trim((string) ($a['label'] ?? '')); + $value = trim((string) ($a['value'] ?? '')); + $unit = trim((string) ($a['unit'] ?? '')); + if ($label === '' && $value === '' && $unit === '') { + continue; + } + + $out[] = ['label' => $label, 'value' => $value, 'unit' => $unit]; + } + + return $out ?: null; + } + + private function buildItemName(string $name, ?array $attrs): string + { + if (! $attrs || count($attrs) === 0) { + return $name; + } + + $parts = []; + foreach ($attrs as $a) { + $value = (string) ($a['value'] ?? ''); + $unit = (string) ($a['unit'] ?? ''); + $chunk = trim($value.$unit); + if ($chunk !== '') { + $parts[] = $chunk; + } + } + + return trim($name.' '.implode(' ', $parts)); + } + + private function buildSpecText(?array $attrs): ?string + { + if (! $attrs || count($attrs) === 0) { + return null; + } + + $parts = []; + foreach ($attrs as $a) { + $label = (string) ($a['label'] ?? ''); + $value = (string) ($a['value'] ?? ''); + $unit = (string) ($a['unit'] ?? ''); + $valueWithUnit = trim($value.$unit); + + if ($label !== '' && $valueWithUnit !== '') { + $parts[] = "{$label} {$valueWithUnit}"; + } elseif ($valueWithUnit !== '') { + $parts[] = $valueWithUnit; + } + } + + return $parts ? implode(', ', $parts) : null; + } + + /** + * options 입력을 [{label, value, unit}] 형태로 정규화. + * - 맵 형태 {"key": "value"}도 배열로 변환 + * - 항상 [{label, value, unit}] 형태로 저장 + */ + private function normalizeOptions(?array $in): ?array + { + if (! $in) { + return null; + } + + // 연관 맵 형태인지 간단 판별 + $isAssoc = array_keys($in) !== range(0, count($in) - 1); + + if ($isAssoc) { + // 맵 형태를 [{label, value, unit}] 배열로 변환 + $out = []; + foreach ($in as $k => $v) { + $label = trim((string) $k); + $value = is_scalar($v) ? trim((string) $v) : json_encode($v, JSON_UNESCAPED_UNICODE); + if ($label !== '' || $value !== '') { + $out[] = ['label' => $label, 'value' => $value, 'unit' => '']; + } + } + + return $out ?: null; + } + + // 리스트(triple) 정규화 + $out = []; + foreach ($in as $a) { + if (! is_array($a)) { + continue; + } + $label = trim((string) ($a['label'] ?? '')); + $value = trim((string) ($a['value'] ?? '')); + $unit = trim((string) ($a['unit'] ?? '')); + + if ($label === '' && $value === '') { + continue; + } + + $out[] = ['label' => $label, 'value' => $value, 'unit' => $unit]; + } + + return $out ?: null; + } +} diff --git a/app/Services/MaterialService.php:Zone.Identifier b/app/Services/MaterialService.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xtenantId(); + + // 부모 제품 유효성 + $this->assertProduct($tenantId, $parentProductId); + + $items = ProductComponent::query() + ->where('tenant_id', $tenantId) + ->where('parent_product_id', $parentProductId) + ->orderBy('sort_order') + ->get(); + + // 리졸브(제품/자재) - ref_id 기준 + $productIds = $items->where('ref_type', 'PRODUCT')->pluck('ref_id')->filter()->unique()->values(); + $materialIds = $items->where('ref_type', 'MATERIAL')->pluck('ref_id')->filter()->unique()->values(); + + $products = $productIds->isNotEmpty() + ? Product::query()->where('tenant_id', $tenantId)->whereIn('id', $productIds)->get(['id', 'code', 'name', 'product_type', 'category_id'])->keyBy('id') + : collect(); + + $materials = $materialIds->isNotEmpty() + ? Material::query()->where('tenant_id', $tenantId)->whereIn('id', $materialIds)->get(['id', 'material_code as code', 'name', 'unit', 'category_id'])->keyBy('id') + : collect(); + + return $items->map(function ($row) use ($products, $materials) { + $base = [ + 'id' => (int) $row->id, + 'ref_type' => $row->ref_type, + 'ref_id' => (int) $row->ref_id, + 'quantity' => $row->quantity, + 'sort_order' => (int) $row->sort_order, + 'is_default' => (int) $row->is_default, + ]; + + if ($row->ref_type === 'PRODUCT') { + $p = $products->get($row->ref_id); + + return $base + [ + 'code' => $p?->code, + 'name' => $p?->name, + 'product_type' => $p?->product_type, + 'category_id' => $p?->category_id, + ]; + } else { // MATERIAL + $m = $materials->get($row->ref_id); + + return $base + [ + 'code' => $m?->code, + 'name' => $m?->name, + 'unit' => $m?->unit, + 'category_id' => $m?->category_id, + ]; + } + })->values(); + } + + /** + * 일괄 업서트 + * items[]: { id?, ref_type: PRODUCT|MATERIAL, ref_id: int, quantity: number, sort_order?: int, is_default?: 0|1 } + */ + public function bulkUpsert(int $parentProductId, array $items): array + { + $tenantId = $this->tenantId(); + $userId = $this->apiUserId(); + + $this->assertProduct($tenantId, $parentProductId); + + if (! is_array($items) || empty($items)) { + throw new BadRequestHttpException(__('error.empty_items')); + } + + $created = 0; + $updated = 0; + $createdIds = []; + $updatedIds = []; + + DB::transaction(function () use ($tenantId, $userId, $parentProductId, $items, &$created, &$updated, &$createdIds, &$updatedIds) { + foreach ($items as $it) { + $payload = $this->validateItem($it); + + // ref 확인 & 자기참조 방지 + $this->assertReference($tenantId, $parentProductId, $payload['ref_type'], (int) $payload['ref_id']); + + if (! empty($it['id'])) { + $pc = ProductComponent::query() + ->where('tenant_id', $tenantId) + ->where('parent_product_id', $parentProductId) + ->find((int) $it['id']); + if (! $pc) { + throw new BadRequestHttpException(__('error.not_found')); + } + + $pc->update([ + 'ref_type' => $payload['ref_type'], + 'ref_id' => (int) $payload['ref_id'], + 'quantity' => $payload['quantity'], + 'sort_order' => $payload['sort_order'] ?? $pc->sort_order, + 'is_default' => $payload['is_default'] ?? $pc->is_default, + 'updated_by' => $userId, + ]); + $updated++; + $updatedIds[] = $pc->id; + } else { + // 신규 + $pc = ProductComponent::create([ + 'tenant_id' => $tenantId, + 'parent_product_id' => $parentProductId, + 'ref_type' => $payload['ref_type'], + 'ref_id' => (int) $payload['ref_id'], + 'quantity' => $payload['quantity'], + 'sort_order' => $payload['sort_order'] ?? 0, + 'is_default' => $payload['is_default'] ?? 0, + 'created_by' => $userId, + ]); + $created++; + $createdIds[] = $pc->id; + } + } + }); + + return [ + 'created' => $created, + 'updated' => $updated, + 'created_ids' => $createdIds, + 'updated_ids' => $updatedIds, + ]; + } + + // 단건 수정 + public function update(int $parentProductId, int $itemId, array $data) + { + $tenantId = $this->tenantId(); + $userId = $this->apiUserId(); + $this->assertProduct($tenantId, $parentProductId); + + $pc = ProductComponent::query() + ->where('tenant_id', $tenantId) + ->where('parent_product_id', $parentProductId) + ->find($itemId); + + if (! $pc) { + throw new BadRequestHttpException(__('error.not_found')); + } + + $v = Validator::make($data, [ + 'ref_type' => 'sometimes|in:PRODUCT,MATERIAL', + 'ref_id' => 'sometimes|integer', + 'quantity' => 'sometimes|numeric|min:0.0001', + 'sort_order' => 'sometimes|integer|min:0', + 'is_default' => 'sometimes|in:0,1', + ]); + $payload = $v->validate(); + + if (isset($payload['ref_type']) || isset($payload['ref_id'])) { + $refType = $payload['ref_type'] ?? $pc->ref_type; + $refId = isset($payload['ref_id']) + ? (int) $payload['ref_id'] + : (int) $pc->ref_id; + + $this->assertReference($tenantId, $parentProductId, $refType, $refId); + + $pc->ref_type = $refType; + $pc->ref_id = $refId; + } + + if (isset($payload['quantity'])) { + $pc->quantity = $payload['quantity']; + } + if (isset($payload['sort_order'])) { + $pc->sort_order = $payload['sort_order']; + } + if (isset($payload['is_default'])) { + $pc->is_default = $payload['is_default']; + } + + $pc->updated_by = $userId; + $pc->save(); + + return $pc->refresh(); + } + + // 삭제 + public function destroy(int $parentProductId, int $itemId): void + { + $tenantId = $this->tenantId(); + $this->assertProduct($tenantId, $parentProductId); + + $pc = ProductComponent::query() + ->where('tenant_id', $tenantId) + ->where('parent_product_id', $parentProductId) + ->find($itemId); + + if (! $pc) { + throw new BadRequestHttpException(__('error.not_found')); + } + $pc->delete(); + } + + // 정렬 변경 + public function reorder(int $parentProductId, array $items): void + { + $tenantId = $this->tenantId(); + $this->assertProduct($tenantId, $parentProductId); + + if (! is_array($items)) { + throw new BadRequestHttpException(__('error.invalid_payload')); + } + + DB::transaction(function () use ($tenantId, $parentProductId, $items) { + foreach ($items as $row) { + if (! isset($row['id'], $row['sort_order'])) { + continue; + } + ProductComponent::query() + ->where('tenant_id', $tenantId) + ->where('parent_product_id', $parentProductId) + ->where('id', (int) $row['id']) + ->update(['sort_order' => (int) $row['sort_order']]); + } + }); + } + + // 요약(간단 합계/건수) + public function summary(int $parentProductId): array + { + $tenantId = $this->tenantId(); + $this->assertProduct($tenantId, $parentProductId); + + $items = ProductComponent::query() + ->where('tenant_id', $tenantId) + ->where('parent_product_id', $parentProductId) + ->get(); + + $cnt = $items->count(); + $cntP = $items->where('ref_type', 'PRODUCT')->count(); + $cntM = $items->where('ref_type', 'MATERIAL')->count(); + $qtySum = (string) $items->sum('quantity'); + + return [ + 'count' => $cnt, + 'count_product' => $cntP, + 'count_material' => $cntM, + 'quantity_sum' => $qtySum, + ]; + } + + // 유효성 검사(중복/자기참조/음수 등) + public function validateBom(int $parentProductId): array + { + $tenantId = $this->tenantId(); + $this->assertProduct($tenantId, $parentProductId); + + $items = ProductComponent::query() + ->where('tenant_id', $tenantId) + ->where('parent_product_id', $parentProductId) + ->orderBy('sort_order') + ->get(); + + $errors = []; + $seen = []; + + foreach ($items as $row) { + if ($row->quantity <= 0) { + $errors[] = ['id' => $row->id, 'error' => 'INVALID_QUANTITY']; + } + $key = $row->ref_type.':'.$row->ref_id; + if (isset($seen[$key])) { + $errors[] = ['id' => $row->id, 'error' => 'DUPLICATE_ITEM']; + } else { + $seen[$key] = true; + } + // 자기참조 + if ($row->ref_type === 'PRODUCT' && (int) $row->ref_id === (int) $parentProductId) { + $errors[] = ['id' => $row->id, 'error' => 'SELF_REFERENCE']; + } + } + + return [ + 'valid' => count($errors) === 0, + 'errors' => $errors, + ]; + } + + // ---------- helpers ---------- + + private function validateItem(array $it): array + { + $v = Validator::make($it, [ + 'id' => 'nullable|integer', + 'ref_type' => 'required|in:PRODUCT,MATERIAL', + 'ref_id' => 'required|integer', + 'quantity' => 'required|numeric|min:0.0001', + 'sort_order' => 'nullable|integer|min:0', + 'is_default' => 'nullable|in:0,1', + ]); + + return $v->validate(); + } + + private function assertProduct(int $tenantId, int $productId): void + { + $exists = Product::query()->where('tenant_id', $tenantId)->where('id', $productId)->exists(); + if (! $exists) { + // ko: 제품 정보를 찾을 수 없습니다. + throw new NotFoundHttpException(__('error.not_found_resource', ['resource' => '제품'])); + } + } + + private function assertReference(int $tenantId, int $parentProductId, string $refType, int $refId): void + { + if ($refType === 'PRODUCT') { + if ($refId === $parentProductId) { + throw new BadRequestHttpException(__('error.invalid_payload')); // 자기참조 방지 + } + $ok = Product::query()->where('tenant_id', $tenantId)->where('id', $refId)->exists(); + if (! $ok) { + throw new BadRequestHttpException(__('error.not_found')); + } + } else { + $ok = Material::query()->where('tenant_id', $tenantId)->where('id', $refId)->exists(); + if (! $ok) { + throw new BadRequestHttpException(__('error.not_found')); + } + } + } + + /** + * 특정 제품의 BOM을 전체 교체(기존 삭제 → 새 데이터 일괄 삽입) + * - $productId: products.id + * - $payload: ['categories' => [ {id?, name?, items: [{ref_type, ref_id, quantity, sort_order?}, ...]}, ... ]] + * 반환: ['deleted_count' => int, 'inserted_count' => int] + */ + public function replaceBom(int $productId, array $payload): array + { + if ($productId <= 0) { + throw new BadRequestHttpException(__('error.bad_request')); // 400 + } + + $tenantId = $this->tenantId(); + $userId = $this->apiUserId(); + + // 0) ====== 빈 카테고리 제거 ====== + $rawCats = Arr::get($payload, 'categories', []); + $normalized = []; + + foreach ((array) $rawCats as $cat) { + $catId = Arr::get($cat, 'id'); + $catName = Arr::get($cat, 'name'); + + $items = array_values(array_filter((array) Arr::get($cat, 'items', []), function ($it) { + $type = Arr::get($it, 'ref_type'); + $id = (int) Arr::get($it, 'ref_id'); + $qty = Arr::get($it, 'quantity'); + + return in_array($type, ['MATERIAL', 'PRODUCT'], true) + && $id > 0 + && is_numeric($qty); + })); + + if (count($items) === 0) { + continue; // 아이템 없으면 skip + } + + $normalized[] = [ + 'id' => $catId, + 'name' => $catName, + 'items' => $items, + ]; + } + + // 🔕 전부 비었으면: 기존 BOM 전체 삭제 후 성공 + if (count($normalized) === 0) { + $deleted = ProductComponent::where('tenant_id', $tenantId) + ->where('parent_product_id', $productId) + ->delete(); + + return [ + 'deleted_count' => $deleted, + 'inserted_count' => 0, + 'message' => '모든 BOM 항목이 비어 기존 데이터를 삭제했습니다.', + ]; + } + + // 1) ====== 검증 ====== + $v = Validator::make( + ['categories' => $normalized], + [ + 'categories' => ['required', 'array', 'min:1'], + 'categories.*.id' => ['nullable', 'integer'], + 'categories.*.name' => ['nullable', 'string', 'max:100'], + 'categories.*.items' => ['required', 'array', 'min:1'], + 'categories.*.items.*.ref_type' => ['required', 'in:MATERIAL,PRODUCT'], + 'categories.*.items.*.ref_id' => ['required', 'integer', 'min:1'], + 'categories.*.items.*.quantity' => ['required', 'numeric', 'min:0'], + 'categories.*.items.*.sort_order' => ['nullable', 'integer', 'min:0'], + ] + ); + if ($v->fails()) { + throw new ValidationException($v, null, __('error.validation_failed')); + } + + // 2) ====== 플랫 레코드 생성 (note 제거) ====== + $rows = []; + $now = now(); + foreach ($normalized as $cat) { + $catId = Arr::get($cat, 'id'); + $catName = Arr::get($cat, 'name'); + + foreach ($cat['items'] as $idx => $item) { + $rows[] = [ + 'tenant_id' => $tenantId, + 'parent_product_id' => $productId, + 'category_id' => $catId, + 'category_name' => $catName, + 'ref_type' => $item['ref_type'], + 'ref_id' => (int) $item['ref_id'], + 'quantity' => (string) $item['quantity'], + 'sort_order' => isset($item['sort_order']) ? (int) $item['sort_order'] : $idx, + 'created_by' => $userId, + 'updated_by' => $userId, + 'created_at' => $now, + 'updated_at' => $now, + ]; + } + } + + // 3) ====== 트랜잭션: 기존 삭제 후 신규 삽입 ====== + return DB::transaction(function () use ($tenantId, $productId, $rows) { + $deleted = ProductComponent::where('tenant_id', $tenantId) + ->where('parent_product_id', $productId) + ->delete(); + + $inserted = 0; + foreach (array_chunk($rows, 500) as $chunk) { + $ok = ProductComponent::insert($chunk); + $inserted += $ok ? count($chunk) : 0; + } + + return [ + 'deleted_count' => $deleted, + 'inserted_count' => $inserted, + 'message' => 'BOM 저장 성공', + ]; + }); + } + + /** 제품별: 현재 BOM에 쓰인 카테고리 */ + public function listCategoriesForProduct(int $productId): array + { + if ($productId <= 0) { + throw new BadRequestHttpException(__('error.bad_request')); + } + + $tenantId = $this->tenantId(); + + $rows = ProductComponent::query() + ->where('tenant_id', $tenantId) + ->where('parent_product_id', $productId) + ->whereNotNull('category_name') + ->select([ + DB::raw('category_id'), + DB::raw('category_name'), + DB::raw('COUNT(*) as count'), + ]) + ->groupBy('category_id', 'category_name') + ->orderByDesc('count') + ->orderBy('category_name') + ->get() + ->toArray(); + + return $rows; + } + + /** 테넌트 전역: 자주 쓰인 카테고리 추천(+검색) */ + public function listCategoriesForTenant(?string $q, int $limit = 20): array + { + $tenantId = $this->tenantId(); + + $query = ProductComponent::query() + ->where('tenant_id', $tenantId) + ->whereNotNull('category_name') + ->select([ + DB::raw('category_id'), + DB::raw('category_name'), + DB::raw('COUNT(*) as count'), + ]) + ->groupBy('category_id', 'category_name'); + + if ($q) { + $query->havingRaw('category_name LIKE ?', ["%{$q}%"]); + } + + $rows = $query + ->orderByDesc('count') + ->orderBy('category_name') + ->limit($limit > 0 ? $limit : 20) + ->get() + ->toArray(); + + return $rows; + } + + public function tree($request, int $productId): array + { + $depth = (int) $request->query('depth', config('products.default_tree_depth', 10)); + $resolver = app(ProductComponentResolver::class); + + // 트리 배열만 반환 (ApiResponse가 바깥에서 래핑) + return $resolver->resolveTree($productId, $depth); + } +} diff --git a/app/Services/ProductBomService.php:Zone.Identifier b/app/Services/ProductBomService.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xtenantId(); + + // 1. SystemFields에서 products 테이블 고정 컬럼 + $systemFields = SystemFields::getReservedKeys(SystemFields::SOURCE_TABLE_PRODUCTS); + + // 2. ItemField에서 storage_type='column'인 필드의 field_key 조회 + $columnFields = ItemField::where('tenant_id', $tenantId) + ->where('source_table', 'products') + ->where('storage_type', 'column') + ->whereNotNull('field_key') + ->pluck('field_key') + ->toArray(); + + // 3. 추가적인 API 전용 필드 (DB 컬럼이 아니지만 API에서 사용하는 필드) + $apiFields = ['item_type', 'type_code', 'bom']; + + return array_unique(array_merge($systemFields, $columnFields, $apiFields)); + } + + /** + * 정의된 필드 외의 동적 필드를 options로 추출 + */ + private function extractDynamicOptions(array $params): array + { + $knownFields = $this->getKnownFields(); + + $dynamicOptions = []; + foreach ($params as $key => $value) { + if (! in_array($key, $knownFields) && $value !== null && $value !== '') { + $dynamicOptions[$key] = $value; + } + } + + return $dynamicOptions; + } + + /** + * 기존 options 배열과 동적 필드를 병합 + */ + private function mergeOptionsWithDynamic($existingOptions, array $dynamicOptions): array + { + if (! is_array($existingOptions) || empty($existingOptions)) { + return $dynamicOptions; + } + + $isAssoc = array_keys($existingOptions) !== range(0, count($existingOptions) - 1); + + if ($isAssoc) { + return array_merge($existingOptions, $dynamicOptions); + } + + foreach ($dynamicOptions as $key => $value) { + $existingOptions[] = ['label' => $key, 'value' => $value]; + } + + return $existingOptions; + } + + /** + * options 입력을 [{label, value, unit}] 형태로 정규화 + */ + private function normalizeOptions(?array $in): ?array + { + if (! $in) { + return null; + } + + $isAssoc = array_keys($in) !== range(0, count($in) - 1); + + if ($isAssoc) { + $out = []; + foreach ($in as $k => $v) { + $label = trim((string) $k); + $value = is_scalar($v) ? trim((string) $v) : json_encode($v, JSON_UNESCAPED_UNICODE); + if ($label !== '' || $value !== '') { + $out[] = ['label' => $label, 'value' => $value, 'unit' => '']; + } + } + + return $out ?: null; + } + + $out = []; + foreach ($in as $a) { + if (! is_array($a)) { + continue; + } + $label = trim((string) ($a['label'] ?? '')); + $value = trim((string) ($a['value'] ?? '')); + $unit = trim((string) ($a['unit'] ?? '')); + + if ($label === '' && $value === '') { + continue; + } + + $out[] = ['label' => $label, 'value' => $value, 'unit' => $unit]; + } + + return $out ?: null; + } + + /** + * 카테고리 트리 전체 조회 (parent_id = null 기준) + */ + public function getCategory($request) + { + $parentId = $request->parentId ?? null; + $group = $request->group ?? 'category'; + + // 재귀적으로 트리 구성 + $list = $this->fetchCategoryTree($parentId, $group); + + return $list; + } + + /** + * 내부 재귀 함수 (하위 카테고리 트리 구조로 구성) + */ + protected function fetchCategoryTree(?int $parentId = null) + { + $tenantId = $this->tenantId(); // Base Service에서 상속받은 메서드 + + $query = Category::query() + ->when($tenantId, fn ($q) => $q->where('tenant_id', $tenantId)) + ->when( + is_null($parentId), + fn ($q) => $q->whereNull('parent_id'), + fn ($q) => $q->where('parent_id', $parentId) + ) + ->where('is_active', 1) + ->orderBy('sort_order'); + + $categories = $query->get(); + + foreach ($categories as $category) { + $children = $this->fetchCategoryTree($category->id); + $category->setRelation('children', $children); + } + + return $categories; + } + + /** + * (예시) 기존의 flat 리스트 조회 + */ + public static function getCategoryFlat($group = 'category') + { + $query = CommonCode::where('code_group', $group)->whereNull('parent_id'); + + return $query->get(); + } + + // 목록/검색 + public function index(array $params) + { + $tenantId = $this->tenantId(); + + $size = (int) ($params['size'] ?? 20); + $q = trim((string) ($params['q'] ?? '')); + $categoryId = $params['category_id'] ?? null; + $productType = $params['product_type'] ?? null; // PRODUCT|PART|SUBASSEMBLY... + $active = $params['active'] ?? null; // 1/0 + + $query = Product::query() + ->with('category:id,name') // 필요한 컬럼만 가져오기 + ->where('tenant_id', $tenantId); + + if ($q !== '') { + $query->where(function ($w) use ($q) { + $w->where('name', 'like', "%{$q}%") + ->orWhere('code', 'like', "%{$q}%") + ->orWhere('description', 'like', "%{$q}%"); + }); + } + if ($categoryId) { + $query->where('category_id', (int) $categoryId); + } + if ($productType) { + $query->where('product_type', $productType); + } + // Note: is_active 필드는 하이브리드 구조로 전환하면서 제거됨 + // 필요시 attributes JSON이나 별도 필드로 관리 + // if ($active !== null && $active !== '') { + // $query->where('is_active', (int) $active); + // } + + $paginator = $query->orderBy('id')->paginate($size); + + // 날짜 형식을 위해 분리 + $paginator->setCollection( + $paginator->getCollection()->transform(function ($item) { + $arr = $item->toArray(); + $arr['created_at'] = $item->created_at + ? $item->created_at->format('Y-m-d') + : null; + + return $arr; + }) + ); + + return $paginator; + } + + // 생성 + public function store(array $data) + { + $tenantId = $this->tenantId(); + $userId = $this->apiUserId(); + + // 동적 필드를 options에 병합 + $dynamicOptions = $this->extractDynamicOptions($data); + if (! empty($dynamicOptions)) { + $existingOptions = $data['options'] ?? []; + $data['options'] = $this->mergeOptionsWithDynamic($existingOptions, $dynamicOptions); + } + + // options 정규화 + if (isset($data['options'])) { + $data['options'] = $this->normalizeOptions($data['options']); + } + + $payload = $data; + + // tenant별 code 유니크 수동 체크 + $dup = Product::query() + ->where('tenant_id', $tenantId) + ->where('code', $payload['code']) + ->exists(); + if ($dup) { + throw new BadRequestHttpException(__('error.duplicate_key')); + } + + // 기본값 설정 + $payload['tenant_id'] = $tenantId; + $payload['created_by'] = $userId; + $payload['is_sellable'] = $payload['is_sellable'] ?? true; + $payload['is_purchasable'] = $payload['is_purchasable'] ?? false; + $payload['is_producible'] = $payload['is_producible'] ?? true; + + return Product::create($payload); + } + + // 단건 + public function show(int $id) + { + $tenantId = $this->tenantId(); + $p = Product::query()->where('tenant_id', $tenantId)->find($id); + if (! $p) { + throw new BadRequestHttpException(__('error.not_found')); + } + + return $p; + } + + // 수정 + public function update(int $id, array $data) + { + $tenantId = $this->tenantId(); + $userId = $this->apiUserId(); + + $p = Product::query()->where('tenant_id', $tenantId)->find($id); + if (! $p) { + throw new BadRequestHttpException(__('error.not_found')); + } + + // 동적 필드를 options에 병합 + $dynamicOptions = $this->extractDynamicOptions($data); + if (! empty($dynamicOptions)) { + $existingOptions = $data['options'] ?? []; + $data['options'] = $this->mergeOptionsWithDynamic($existingOptions, $dynamicOptions); + } + + // options 정규화 + if (isset($data['options'])) { + $data['options'] = $this->normalizeOptions($data['options']); + } + + $payload = $data; + + // code 변경 시 중복 체크 + if (isset($payload['code']) && $payload['code'] !== $p->code) { + $dup = Product::query() + ->where('tenant_id', $tenantId) + ->where('code', $payload['code']) + ->exists(); + if ($dup) { + throw new BadRequestHttpException(__('error.duplicate_key')); + } + } + + $payload['updated_by'] = $userId; + $p->update($payload); + + return $p->refresh(); + } + + // 삭제(soft) + public function destroy(int $id): void + { + $tenantId = $this->tenantId(); + $p = Product::query()->where('tenant_id', $tenantId)->find($id); + if (! $p) { + throw new BadRequestHttpException(__('error.not_found')); + } + $p->delete(); + } + + // 간편 검색(모달/드롭다운) + public function search(array $params) + { + $tenantId = $this->tenantId(); + $q = trim((string) ($params['q'] ?? '')); + $lim = (int) ($params['limit'] ?? 20); + + $qr = Product::query()->where('tenant_id', $tenantId); + if ($q !== '') { + $qr->where(function ($w) use ($q) { + $w->where('name', 'like', "%{$q}%") + ->orWhere('code', 'like', "%{$q}%"); + }); + } + + return $qr->orderBy('name')->limit($lim)->get(['id', 'code', 'name', 'product_type', 'category_id']); + } + + // Note: toggle 메서드는 is_active 필드 제거로 인해 비활성화됨 + // 필요시 attributes JSON이나 별도 필드로 구현 + // public function toggle(int $id) + // { + // $tenantId = $this->tenantId(); + // $userId = $this->apiUserId(); + // + // $p = Product::query()->where('tenant_id', $tenantId)->find($id); + // if (! $p) { + // throw new BadRequestHttpException(__('error.not_found')); + // } + // + // $p->is_active = $p->is_active ? 0 : 1; + // $p->updated_by = $userId; + // $p->save(); + // + // return ['id' => $p->id, 'is_active' => (int) $p->is_active]; + // } +} diff --git a/app/Services/ProductService.php:Zone.Identifier b/app/Services/ProductService.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xtenantId = $this->tenantId ?? $this->tenantId(); + } + + /** 테넌트별로 "제품처럼 자식이 있을 수 있는" ref_type 목록 */ + protected function productLikeTypes(): array + { + $all = config('products.product_like_types', []); + $byTenant = Arr::get($all, (string) $this->tenantId, null); + + if (is_array($byTenant) && $byTenant) { + return $byTenant; + } + + return Arr::get($all, '*', ['PRODUCT']); + } + + /** 한 부모 ID에 달린 컴포넌트 라인들 로드 (메모이즈) */ + protected function getLinesForParent(int $parentId): array + { + // 간단 메모이즈(요청 범위); 대량 호출 방지 + static $memo = []; + if (array_key_exists($parentId, $memo)) { + return $memo[$parentId]; + } + + $rows = ProductComponent::where('tenant_id', $this->tenantId) + ->where('parent_product_id', $parentId) + ->orderBy('sort_order')->orderBy('id') + ->get([ + 'id', 'tenant_id', 'parent_product_id', + 'category_id', 'category_name', + 'ref_type', 'ref_id', 'quantity', 'sort_order', + ]) + ->map(fn ($r) => $r->getAttributes()) // ✅ 핵심 수정 + ->all(); + + return $memo[$parentId] = $rows; + } + + /** ref_type/ref_id 에 해당하는 노드의 "표시용 정보"를 로드 */ + protected function resolveNodeInfo(string $refType, int $refId): array + { + if ($refType === 'PRODUCT') { + $p = Product::query() + ->where('tenant_id', $this->tenantId) + ->find($refId, ['id', 'code', 'name', 'product_type', 'category_id']); + if (! $p) { + return [ + 'id' => $refId, + 'code' => null, + 'name' => null, + 'product_type' => null, + 'category_id' => null, + ]; + } + + return [ + 'id' => (int) $p->id, + 'code' => $p->code, + 'name' => $p->name, + 'product_type' => $p->product_type, + 'category_id' => $p->category_id, + ]; + } + + // ✅ MATERIAL 분기: materials 테이블 스키마 반영 + if ($refType === 'MATERIAL') { + $m = DB::table('materials') + ->where('tenant_id', $this->tenantId) + ->where('id', $refId) + ->whereNull('deleted_at') // 소프트 삭제 고려 + ->first([ + 'id', + 'material_code', // 코드 + 'item_name', // 표시명(있으면 우선) + 'name', // fallback 표시명 + 'specification', // 규격 + 'unit', + 'category_id', + ]); + + if (! $m) { + return [ + 'id' => (int) $refId, + 'code' => null, + 'name' => null, + 'unit' => null, + 'category_id' => null, + ]; + } + + // item_name 우선, 없으면 name 사용 + $displayName = $m->item_name ?: $m->name; + + return [ + 'id' => (int) $m->id, + 'code' => $m->material_code, // 표준 코드 필드 + 'name' => $displayName, // 사용자에게 보일 이름 + 'unit' => $m->unit, + 'spec' => $m->specification, // 있으면 프론트에서 활용 가능 + 'category_id' => $m->category_id, + ]; + } + + // 알 수 없는 타입 폴백 + return [ + 'id' => $refId, + 'code' => null, + 'name' => null, + ]; + } + + /** + * 단일 제품을 루트로 트리를 생성 (재귀 / 사이클 방지 / 깊이 제한) + * + * @param int $productId 루트 제품 ID + * @param int|null $maxDepth 최대 깊이(루트=0). null 이면 config default + * @return array 트리 구조 + */ + public function resolveTree(int $productId, ?int $maxDepth = null): array + { + $maxDepth = $maxDepth ?? (int) config('products.default_tree_depth', 10); + + $root = Product::query() + ->where('tenant_id', $this->tenantId) + ->findOrFail($productId, ['id', 'code', 'name', 'product_type', 'category_id']); + + $visited = []; // 사이클 방지용 (product id 기준) + + $node = [ + 'type' => 'PRODUCT', + 'id' => $root->id, + 'code' => $root->code, + 'name' => $root->name, + 'product_type' => $root->product_type, + 'category_id' => $root->category_id, + 'quantity' => 1, // 루트는 수량 1로 간주 + 'category' => null, // 루트는 임의 + 'children' => [], + 'depth' => 0, + ]; + + $node['children'] = $this->resolveChildren($root->id, 0, $maxDepth, $visited); + + return $node; + } + + /** + * 하위 노드(들) 재귀 확장 + * + * @param array $visited product-id 기준 사이클 방지 + */ + protected function resolveChildren(int $parentId, int $depth, int $maxDepth, array &$visited): array + { + // 깊이 제한 + if ($depth >= $maxDepth) { + return []; + } + + $lines = $this->getLinesForParent($parentId); + if (! $lines) { + return []; + } + + $productLike = $this->productLikeTypes(); + $children = []; + + foreach ($lines as $line) { + $refType = (string) $line['ref_type']; + $refId = (int) $line['ref_id']; + $qty = (float) $line['quantity']; + + if (! $refType || $refId <= 0) { + // 로그 남기고 스킵 + // logger()->warning('Invalid component line', ['line' => $line]); + continue; + } + + $info = $this->resolveNodeInfo($refType, $refId); + + $child = [ + 'type' => $refType, + 'id' => $info['id'] ?? $refId, + 'code' => $info['code'] ?? null, + 'name' => $info['name'] ?? null, + 'product_type' => $info['product_type'] ?? null, + 'category_id' => $info['category_id'] ?? null, + 'quantity' => $qty, + 'category' => [ + 'id' => $line['category_id'], + 'name' => $line['category_name'], + ], + 'sort_order' => (int) $line['sort_order'], + 'children' => [], + 'depth' => $depth + 1, + ]; + + // 제품처럼 자식이 달릴 수 있는 타입이면 재귀 + if (in_array($refType, $productLike, true)) { + // 사이클 방지: 같은 product id 재방문 금지 + $pid = (int) $child['id']; + if ($pid > 0) { + if (isset($visited[$pid])) { + $child['cycle'] = true; // 표식만 남기고 children 안탐 + } else { + $visited[$pid] = true; + $child['children'] = $this->resolveChildren($pid, $depth + 1, $maxDepth, $visited); + unset($visited[$pid]); // 백트래킹 + } + } + } + + $children[] = $child; + } + + return $children; + } +} diff --git a/app/Services/Products/ProductComponentResolver.php:Zone.Identifier b/app/Services/Products/ProductComponentResolver.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xunsignedBigInteger('tenant_id')->nullable()->after('id')->comment('테넌트ID'); + $table->index('tenant_id', 'idx_work_order_items_tenant'); + }); + + // 기존 데이터 업데이트 + DB::statement(' + UPDATE work_order_items wi + JOIN work_orders wo ON wi.work_order_id = wo.id + SET wi.tenant_id = wo.tenant_id + '); + + // nullable 제거 + Schema::table('work_order_items', function (Blueprint $table) { + $table->unsignedBigInteger('tenant_id')->nullable(false)->change(); + }); + + // 2. work_order_bending_details + Schema::table('work_order_bending_details', function (Blueprint $table) { + $table->unsignedBigInteger('tenant_id')->nullable()->after('id')->comment('테넌트ID'); + $table->index('tenant_id', 'idx_work_order_bending_details_tenant'); + }); + + DB::statement(' + UPDATE work_order_bending_details wbd + JOIN work_orders wo ON wbd.work_order_id = wo.id + SET wbd.tenant_id = wo.tenant_id + '); + + Schema::table('work_order_bending_details', function (Blueprint $table) { + $table->unsignedBigInteger('tenant_id')->nullable(false)->change(); + }); + + // 3. work_order_issues + Schema::table('work_order_issues', function (Blueprint $table) { + $table->unsignedBigInteger('tenant_id')->nullable()->after('id')->comment('테넌트ID'); + $table->index('tenant_id', 'idx_work_order_issues_tenant'); + }); + + DB::statement(' + UPDATE work_order_issues woi + JOIN work_orders wo ON woi.work_order_id = wo.id + SET woi.tenant_id = wo.tenant_id + '); + + Schema::table('work_order_issues', function (Blueprint $table) { + $table->unsignedBigInteger('tenant_id')->nullable(false)->change(); + }); + } + + public function down(): void + { + Schema::table('work_order_items', function (Blueprint $table) { + $table->dropIndex('idx_work_order_items_tenant'); + $table->dropColumn('tenant_id'); + }); + + Schema::table('work_order_bending_details', function (Blueprint $table) { + $table->dropIndex('idx_work_order_bending_details_tenant'); + $table->dropColumn('tenant_id'); + }); + + Schema::table('work_order_issues', function (Blueprint $table) { + $table->dropIndex('idx_work_order_issues_tenant'); + $table->dropColumn('tenant_id'); + }); + } +}; diff --git a/database/migrations/2025_01_08_100000_add_tenant_id_to_work_order_sub_tables.php:Zone.Identifier b/database/migrations/2025_01_08_100000_add_tenant_id_to_work_order_sub_tables.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xbigIncrements('id'); + $table->unsignedBigInteger('tenant_id')->comment('테넌트ID'); + $table->unsignedBigInteger('work_order_id')->comment('작업지시ID'); + $table->unsignedBigInteger('user_id')->comment('담당자ID'); + $table->boolean('is_primary')->default(false)->comment('주담당자 여부'); + $table->timestamps(); + + // Indexes + $table->unique(['work_order_id', 'user_id'], 'uq_work_order_assignees'); + $table->index(['tenant_id', 'work_order_id'], 'idx_wo_assignees_tenant_wo'); + $table->index(['tenant_id', 'user_id'], 'idx_wo_assignees_tenant_user'); + + // Foreign keys + $table->foreign('work_order_id') + ->references('id') + ->on('work_orders') + ->onDelete('cascade'); + }); + } + + public function down(): void + { + Schema::dropIfExists('work_order_assignees'); + } +}; diff --git a/database/migrations/2025_01_09_100000_create_work_order_assignees_table.php:Zone.Identifier b/database/migrations/2025_01_09_100000_create_work_order_assignees_table.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xstring('account_type', 30)->default('보통예금')->after('account_holder')->comment('예금종류'); + + // 금액 정보 + $table->decimal('balance', 18, 2)->default(0)->after('account_name')->comment('잔액'); + $table->string('currency', 3)->default('KRW')->after('balance')->comment('통화'); + + // 날짜 정보 + $table->date('opened_at')->nullable()->after('currency')->comment('개설일자'); + $table->timestamp('last_transaction_at')->nullable()->after('opened_at')->comment('최종거래일시'); + + // 추가 정보 + $table->string('branch_name', 100)->nullable()->after('last_transaction_at')->comment('지점명'); + $table->text('memo')->nullable()->after('branch_name')->comment('메모'); + + // 정렬 순서 + $table->unsignedInteger('sort_order')->default(0)->after('is_primary')->comment('정렬순서'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('bank_accounts', function (Blueprint $table) { + $table->dropColumn([ + 'account_type', + 'balance', + 'currency', + 'opened_at', + 'last_transaction_at', + 'branch_name', + 'memo', + 'sort_order', + ]); + }); + } +}; diff --git a/database/migrations/2026_01_20_100001_add_columns_to_bank_accounts_table.php:Zone.Identifier b/database/migrations/2026_01_20_100001_add_columns_to_bank_accounts_table.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xid(); + $table->foreignId('tenant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('bank_account_id')->constrained('bank_accounts')->cascadeOnDelete(); + + // 거래 정보 + $table->string('transaction_type', 20)->comment('거래유형: deposit(입금), withdrawal(출금), transfer(이체)'); + $table->decimal('amount', 18, 2)->comment('거래금액'); + $table->decimal('balance_after', 18, 2)->comment('거래 후 잔액'); + + // 날짜 + $table->date('transaction_date')->comment('거래일자'); + $table->time('transaction_time')->nullable()->comment('거래시간'); + + // 상세 정보 + $table->string('description', 255)->nullable()->comment('적요'); + $table->string('counterparty', 100)->nullable()->comment('거래상대방'); + $table->string('reference_number', 100)->nullable()->comment('참조번호'); + + // 분류 + $table->string('category', 50)->nullable()->comment('거래분류'); + $table->foreignId('related_order_id')->nullable()->comment('관련 주문 ID'); + $table->foreignId('related_payment_id')->nullable()->comment('관련 결제 ID'); + + // 상태 + $table->boolean('is_reconciled')->default(false)->comment('대사완료 여부'); + $table->timestamp('reconciled_at')->nullable()->comment('대사완료 일시'); + + // 추가 정보 + $table->text('memo')->nullable()->comment('메모'); + $table->json('options')->nullable()->comment('추가 옵션'); + + // 감사 필드 + $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete(); + $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete(); + $table->foreignId('deleted_by')->nullable()->constrained('users')->nullOnDelete(); + + $table->timestamps(); + $table->softDeletes(); + + // 인덱스 + $table->index('tenant_id', 'idx_bank_transactions_tenant'); + $table->index('bank_account_id', 'idx_bank_transactions_account'); + $table->index('transaction_date', 'idx_bank_transactions_date'); + $table->index('transaction_type', 'idx_bank_transactions_type'); + $table->index('is_reconciled', 'idx_bank_transactions_reconciled'); + $table->index('deleted_at', 'idx_bank_transactions_deleted'); + $table->index(['tenant_id', 'transaction_date'], 'idx_bank_transactions_tenant_date'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('bank_transactions'); + } +}; diff --git a/database/migrations/2026_01_20_100002_create_bank_transactions_table.php:Zone.Identifier b/database/migrations/2026_01_20_100002_create_bank_transactions_table.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xid(); + $table->unsignedBigInteger('tenant_id')->comment('테넌트 ID'); + + // 기본 정보 + $table->string('title', 200)->comment('일정명'); + $table->text('description')->nullable()->comment('설명'); + + // 일정 유형: income(입금예정), expense(지급예정) + $table->enum('schedule_type', ['income', 'expense'])->comment('일정유형: income=입금, expense=지급'); + + // 일정 정보 + $table->date('scheduled_date')->comment('예정일'); + $table->decimal('amount', 18, 2)->default(0)->comment('금액'); + $table->string('currency', 3)->default('KRW')->comment('통화'); + + // 관련 정보 + $table->unsignedBigInteger('related_bank_account_id')->nullable()->comment('관련 계좌 ID'); + $table->string('counterparty', 200)->nullable()->comment('거래상대방'); + $table->string('category', 50)->nullable()->comment('분류'); + + // 상태: pending(예정), completed(완료), cancelled(취소) + $table->enum('status', ['pending', 'completed', 'cancelled'])->default('pending')->comment('상태'); + + // 반복 설정 + $table->boolean('is_recurring')->default(false)->comment('정기 여부'); + $table->string('recurrence_rule', 100)->nullable()->comment('반복 규칙 (daily, weekly, monthly, yearly)'); + $table->date('recurrence_end_date')->nullable()->comment('반복 종료일'); + + // 완료 정보 + $table->date('completed_date')->nullable()->comment('실제 완료일'); + $table->decimal('completed_amount', 18, 2)->nullable()->comment('실제 완료 금액'); + + // 추가 정보 + $table->text('memo')->nullable()->comment('메모'); + + // 감사 필드 + $table->unsignedBigInteger('created_by')->nullable()->comment('생성자 ID'); + $table->unsignedBigInteger('updated_by')->nullable()->comment('수정자 ID'); + $table->unsignedBigInteger('deleted_by')->nullable()->comment('삭제자 ID'); + + $table->timestamps(); + $table->softDeletes(); + + // 인덱스 + $table->index('tenant_id', 'idx_fund_schedules_tenant'); + $table->index('scheduled_date', 'idx_fund_schedules_date'); + $table->index('schedule_type', 'idx_fund_schedules_type'); + $table->index('status', 'idx_fund_schedules_status'); + $table->index(['tenant_id', 'scheduled_date'], 'idx_fund_schedules_tenant_date'); + $table->index('deleted_at', 'idx_fund_schedules_deleted'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('fund_schedules'); + } +}; diff --git a/database/migrations/2026_01_20_110001_create_fund_schedules_table.php:Zone.Identifier b/database/migrations/2026_01_20_110001_create_fund_schedules_table.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2x $tenantId, + 'bank_code' => '004', + 'bank_name' => '국민은행', + 'account_number' => '123-456-789012', + 'account_holder' => '주식회사 코드보잇지엑스', + 'account_name' => '주거래 계좌', + 'account_type' => '보통예금', + 'balance' => 450000000, // 4.5억 + 'currency' => 'KRW', + 'opened_at' => '2023-01-15', + 'last_transaction_at' => '2026-01-15 14:30:00', + 'branch_name' => '역삼지점', + 'memo' => '주거래 계좌', + 'status' => 'active', + 'is_primary' => true, + 'sort_order' => 1, + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'bank_code' => '088', + 'bank_name' => '신한은행', + 'account_number' => '234-567-890123', + 'account_holder' => '주식회사 코드보잇지엑스', + 'account_name' => '법인카드 결제', + 'account_type' => '법인카드 출금', + 'balance' => 90000000, // 9천만원 + 'currency' => 'KRW', + 'opened_at' => '2023-01-15', + 'last_transaction_at' => '2026-01-15 11:20:00', + 'branch_name' => '강남지점', + 'memo' => '법인카드 결제 계좌', + 'status' => 'active', + 'is_primary' => false, + 'sort_order' => 2, + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'bank_code' => '020', + 'bank_name' => '우리은행', + 'account_number' => '345-678-901234', + 'account_holder' => '주식회사 코드보잇지엑스', + 'account_name' => '정기예금', + 'account_type' => '정기예금', + 'balance' => 200000000, // 2억 + 'currency' => 'KRW', + 'opened_at' => '2024-06-01', + 'last_transaction_at' => '2026-01-01 09:00:00', + 'branch_name' => '테헤란로지점', + 'memo' => '정기예금 (만기 2027-06-01)', + 'status' => 'active', + 'is_primary' => false, + 'sort_order' => 3, + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'bank_code' => '081', + 'bank_name' => '하나은행', + 'account_number' => '456-789-012345', + 'account_holder' => '주식회사 코드보잇지엑스', + 'account_name' => '급여계좌', + 'account_type' => '보통예금', + 'balance' => 75000000, // 7천5백만원 + 'currency' => 'KRW', + 'opened_at' => '2023-03-20', + 'last_transaction_at' => '2026-01-14 16:45:00', + 'branch_name' => '선릉역지점', + 'memo' => '급여 지급 계좌', + 'status' => 'active', + 'is_primary' => false, + 'sort_order' => 4, + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'bank_code' => '011', + 'bank_name' => '농협은행', + 'account_number' => '567-890-123456', + 'account_holder' => '주식회사 코드보잇지엑스', + 'account_name' => '퇴직금 적금', + 'account_type' => '적금', + 'balance' => 50000000, // 5천만원 + 'currency' => 'KRW', + 'opened_at' => '2024-01-01', + 'last_transaction_at' => '2026-01-10 10:00:00', + 'branch_name' => '강남중앙지점', + 'memo' => '직원 퇴직금 적립', + 'status' => 'active', + 'is_primary' => false, + 'sort_order' => 5, + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + ]; + + // 계좌 데이터 삽입 + $accountIds = []; + foreach ($accounts as $account) { + $id = DB::table('bank_accounts')->insertGetId($account); + $accountIds[$account['account_number']] = $id; + } + + $this->command->info('계좌 5개 생성 완료'); + + // 거래내역 데이터 (국민은행 계좌 기준) + $transactions = [ + [ + 'tenant_id' => $tenantId, + 'bank_account_id' => $accountIds['123-456-789012'], + 'transaction_type' => 'deposit', + 'amount' => 50000000, + 'balance_after' => 450000000, + 'transaction_date' => '2026-01-15', + 'transaction_time' => '14:30:00', + 'description' => '프로젝트 대금 입금', + 'counterparty' => '주식회사 클라이언트A', + 'reference_number' => 'INV-2026-0115', + 'category' => '매출', + 'is_reconciled' => true, + 'reconciled_at' => '2026-01-15 15:00:00', + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'bank_account_id' => $accountIds['123-456-789012'], + 'transaction_type' => 'withdrawal', + 'amount' => 5000000, + 'balance_after' => 400000000, + 'transaction_date' => '2026-01-14', + 'transaction_time' => '11:20:00', + 'description' => '사무실 임대료', + 'counterparty' => '강남빌딩관리(주)', + 'reference_number' => 'RENT-2026-01', + 'category' => '임대료', + 'is_reconciled' => true, + 'reconciled_at' => '2026-01-14 14:00:00', + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'bank_account_id' => $accountIds['123-456-789012'], + 'transaction_type' => 'transfer', + 'amount' => 30000000, + 'balance_after' => 405000000, + 'transaction_date' => '2026-01-13', + 'transaction_time' => '09:00:00', + 'description' => '급여계좌 이체', + 'counterparty' => '하나은행 급여계좌', + 'reference_number' => 'TRF-2026-0113', + 'category' => '급여', + 'is_reconciled' => true, + 'reconciled_at' => '2026-01-13 10:00:00', + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'bank_account_id' => $accountIds['123-456-789012'], + 'transaction_type' => 'deposit', + 'amount' => 25000000, + 'balance_after' => 435000000, + 'transaction_date' => '2026-01-10', + 'transaction_time' => '16:45:00', + 'description' => '유지보수 계약금', + 'counterparty' => '주식회사 클라이언트B', + 'reference_number' => 'MAINT-2026-001', + 'category' => '매출', + 'is_reconciled' => false, + 'reconciled_at' => null, + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'bank_account_id' => $accountIds['123-456-789012'], + 'transaction_type' => 'withdrawal', + 'amount' => 2500000, + 'balance_after' => 410000000, + 'transaction_date' => '2026-01-08', + 'transaction_time' => '14:00:00', + 'description' => '클라우드 서비스 이용료', + 'counterparty' => 'AWS Korea', + 'reference_number' => 'AWS-2026-01', + 'category' => '운영비', + 'is_reconciled' => false, + 'reconciled_at' => null, + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + ]; + + // 거래내역 삽입 + DB::table('bank_transactions')->insert($transactions); + + $this->command->info('거래내역 5개 생성 완료'); + + // 신한은행 거래내역 + $shinhanTransactions = [ + [ + 'tenant_id' => $tenantId, + 'bank_account_id' => $accountIds['234-567-890123'], + 'transaction_type' => 'withdrawal', + 'amount' => 1500000, + 'balance_after' => 90000000, + 'transaction_date' => '2026-01-15', + 'transaction_time' => '11:20:00', + 'description' => '법인카드 결제', + 'counterparty' => '신한카드', + 'reference_number' => 'CARD-2026-0115', + 'category' => '카드결제', + 'is_reconciled' => true, + 'reconciled_at' => '2026-01-15 12:00:00', + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'bank_account_id' => $accountIds['234-567-890123'], + 'transaction_type' => 'deposit', + 'amount' => 10000000, + 'balance_after' => 91500000, + 'transaction_date' => '2026-01-10', + 'transaction_time' => '09:30:00', + 'description' => '카드결제계좌 입금', + 'counterparty' => '국민은행 주거래계좌', + 'reference_number' => 'TRF-2026-0110', + 'category' => '이체', + 'is_reconciled' => true, + 'reconciled_at' => '2026-01-10 10:00:00', + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + ]; + + DB::table('bank_transactions')->insert($shinhanTransactions); + + $this->command->info('신한은행 거래내역 2개 생성 완료'); + + $this->command->info('BankAccountSeeder 완료: 계좌 5개, 거래내역 7개'); + } +} diff --git a/database/seeders/BankAccountSeeder.php:Zone.Identifier b/database/seeders/BankAccountSeeder.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xyear; + $month = now()->month; + + // 자금계획일정 데이터 + $schedules = [ + // 입금 예정 + [ + 'tenant_id' => $tenantId, + 'title' => '(주)스마트팩토리 개발비 1차', + 'description' => 'ERP 시스템 개발 프로젝트 1차 중도금', + 'schedule_type' => 'income', + 'scheduled_date' => sprintf('%04d-%02d-10', $year, $month), + 'amount' => 100000000, // 1억원 + 'currency' => 'KRW', + 'counterparty' => '(주)스마트팩토리', + 'category' => '매출', + 'status' => 'pending', + 'is_recurring' => false, + 'recurrence_rule' => null, + 'memo' => '계약서 기준 착수금 30%, 중도금 40%, 잔금 30%', + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'title' => '영업파트너 수수료 지급', + 'description' => '1월 영업 수수료 정산', + 'schedule_type' => 'expense', + 'scheduled_date' => sprintf('%04d-%02d-10', $year, $month), + 'amount' => 20000000, // 2천만원 + 'currency' => 'KRW', + 'counterparty' => '영업파트너', + 'category' => '매입', + 'status' => 'pending', + 'is_recurring' => false, + 'recurrence_rule' => null, + 'memo' => null, + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'title' => '(주)디지털제조 개발비 잔금', + 'description' => 'MES 시스템 개발 프로젝트 잔금', + 'schedule_type' => 'income', + 'scheduled_date' => sprintf('%04d-%02d-15', $year, $month), + 'amount' => 30000000, // 3천만원 + 'currency' => 'KRW', + 'counterparty' => '(주)디지털제조', + 'category' => '매출', + 'status' => 'pending', + 'is_recurring' => false, + 'recurrence_rule' => null, + 'memo' => '검수 완료 후 지급', + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'title' => '직원 급여 지급', + 'description' => sprintf('%d년 %d월 급여', $year, $month), + 'schedule_type' => 'expense', + 'scheduled_date' => sprintf('%04d-%02d-25', $year, $month), + 'amount' => 25000000, // 2천5백만원 + 'currency' => 'KRW', + 'counterparty' => '직원', + 'category' => '급여', + 'status' => 'pending', + 'is_recurring' => true, + 'recurrence_rule' => 'monthly', + 'memo' => '매월 25일 정기 지급', + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'title' => '구독료 CMS 출금', + 'description' => '클라우드 서비스 월 구독료', + 'schedule_type' => 'expense', + 'scheduled_date' => sprintf('%04d-%02d-28', $year, $month), + 'amount' => 8500000, // 850만원 + 'currency' => 'KRW', + 'counterparty' => 'AWS/Azure', + 'category' => '운영비', + 'status' => 'pending', + 'is_recurring' => true, + 'recurrence_rule' => 'monthly', + 'memo' => 'AWS + Azure 클라우드 비용', + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + // 다음 달 일정도 추가 + [ + 'tenant_id' => $tenantId, + 'title' => '사무실 임대료', + 'description' => '강남 오피스 임대료', + 'schedule_type' => 'expense', + 'scheduled_date' => sprintf('%04d-%02d-05', $month == 12 ? $year + 1 : $year, $month == 12 ? 1 : $month + 1), + 'amount' => 5000000, // 500만원 + 'currency' => 'KRW', + 'counterparty' => '강남빌딩관리(주)', + 'category' => '임대료', + 'status' => 'pending', + 'is_recurring' => true, + 'recurrence_rule' => 'monthly', + 'memo' => '매월 5일 자동이체', + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'tenant_id' => $tenantId, + 'title' => '유지보수 계약금 입금', + 'description' => '연간 유지보수 계약 선금', + 'schedule_type' => 'income', + 'scheduled_date' => sprintf('%04d-%02d-15', $month == 12 ? $year + 1 : $year, $month == 12 ? 1 : $month + 1), + 'amount' => 50000000, // 5천만원 + 'currency' => 'KRW', + 'counterparty' => '(주)테크솔루션', + 'category' => '매출', + 'status' => 'pending', + 'is_recurring' => false, + 'recurrence_rule' => null, + 'memo' => '2026년 연간 유지보수 계약', + 'created_by' => $userId, + 'created_at' => now(), + 'updated_at' => now(), + ], + ]; + + // 데이터 삽입 + DB::table('fund_schedules')->insert($schedules); + + $this->command->info('FundScheduleSeeder 완료: 자금계획일정 ' . count($schedules) . '개 생성'); + } +} diff --git a/database/seeders/FundScheduleSeeder.php:Zone.Identifier b/database/seeders/FundScheduleSeeder.php:Zone.Identifier new file mode 100644 index 0000000000000000000000000000000000000000..d6c1ec682968c796b9f5e9e080cc6f674b57c766 GIT binary patch literal 25 dcma!!%Fjy;DN4*MPD?F{<>dl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2xdl#JyUFr831@K2x